简体   繁体   中英

setState in react and passing props with functions

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM