i'm new to react and just got into the field of props and passing functions, and my task was to make the app work with the given component, I tried to fix it and I got in one of those moment when you fix something and you don't now what happened:)
the issue was cutting part of the main code and make another component:
this is the main app code:
import React, { useState } from "react";
import ToDoItem from "./ToDoItem";
import InputArea from "./InputArea";
function App() {
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);
function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}
function addItem() {
setItems(prevItems => {
return [...prevItems, inputText];
});
setInputText("");
}
function deleteItem(id) {
setItems(prevItems => {
return prevItems.filter((item, index) => {
return index !== id;
});
});
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<InputArea
inputText={inputText}
onTyping={handleChange}
addItem={addItem}
/>
<div>
<ul>
{items.map((todoItem, index) => (
<ToDoItem
key={index}
id={index}
text={todoItem}
onChecked={deleteItem}
/>
))}
</ul>
</div>
</div>
);
}
export default App;
and this is the component code:
import React from "react";
function InputArea(props) {
return (
<div className="form">
<input onChange={(e)=>{
props.onTyping(e)
}} type="text" value={props.inputText} />
<button onClick={()=>{
props.addItem()
}}>
<span>Add</span>
</button>
</div>
);
}
export default InputArea;
so... the problem was to try passing the state of the input field from the main app to the component and I faced the issue of const newValue = event.target.value;
is not defined, and then I tried this in the component code <input onChange={(e)=>{ props.onTyping(e) }}
before it was <input onChange={()=>{ props.onTyping() }}
and somehow it works just fine and perfectly,?!, can someone please explain why and how did it worked?
PS: I'm not good at writing questions so please any comment on the question is helpful to improve my structure, thank you.
React has one-way data binding, that means, the state itself is the true source of change. You can't change something in the input field and expect it to automatically update the state that field use(Such magic happens in Angular- two way data binding). With this in mind let's look into your code:-
<InputArea
inputText={inputText}
onTyping={handleChange}
addItem={addItem}
/>
This component has an input field whose value
is decided from inputText
prop which is a state in its parent component App
. So when you start typing in this input field, you would want to update the inputText
state of the App
component so that the changed props
are passed to the InputArea
component. For facilitating this, you have passed handleChange
aliased as onTyping
as a prop. Now you bind this prop to your onChange
handler on input field which triggers whenever you type in the field. So now you just need to ensure to pass the event
object to onTyping
handler. This will call your handleChange
with that event
object and now you can make use of event.target.value
and set it to your inputText
.
You can change
<input onChange={(e)=>
props.onTyping(e)
}
to
<input onChange={
props.onTyping
}
And it will work the same way. In second style, event
object is passed implicitly.
If you look at what the onTyping function is, it's a reference to the handleChange function. If you look at the definition of the handleChange function, you see that it takes an event
argument. In your line that didn't work:
<input onChange={()=>{ props.onTyping() }}
You weren't passing anything - there's nothing in the parenthesis - so this line in the handChange function:
const newValue = event.target.value;
sets newValue to undefined because event
wasn't passed in.
Your new line adds in e, or the event, as an argument, and hence it works. The event is indeed generated by default, but you need to pass that event as an argument, otherwise the function won't get it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.