0

i have two component App and Child .And whenever there's a change in the input field of the Child component it should update the change in the App component instantly. But rather than updating the App instantly it is one step behind. here is the code :-

App component

function App() {
  const [ChildData, setChildData] = useState("");
  
  
  return (
    <div>
      <div>
        <Child passdata={setChldData}/>
      </div>
      <div>
        {ChildData.name}
      </div>
      
    </div>
  )
}

Child component

function Child(props) {
    const [Data, setData] = useState({ name:'' ,title:'' ,phone:'' });
  
    const handleChange = (e)=>{
        setData({...Data, [e.target.name] : e.target.value})
        props.passdata(Data)
    }
  
    return (
    <div>
      <h2>Child Data</h2>
      <input type="text" name='name' onChange={handleChange} placeholder={"Name"}/>
      <input type="text" name='title' onChange={handleChange} placeholder={"Title"}/>
      <input type="number" name='phone' onChange={handleChange} placeholder={"Phone number"}/>

    </div>
  )
}

Whenever there;s a change in the input field it is one step behind. i want the App component change simultaneously with the input from Child

  • Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – David Jan 24 '23 at 13:06
  • yes. but it would be nice if you have something simpler than that ; ) . – Hamdan Salih Jan 24 '23 at 13:19
  • 1
    "Simpler" how? The value you're looking to send to `props.passdata` is `{...Data, [e.target.name] : e.target.value}`, not `Data`. That's all. – David Jan 24 '23 at 13:20

1 Answers1

1
function Child(props) {
    const [Data, setData] = useState({ name:'' ,title:'' ,phone:'' });
  
    const handleChange = (e)=>{
        setData((prevData) => {
            const newData = {...prevData, [e.target.name] : e.target.value}
            props.passData(newData)
            return newData
        })
    }
  
    return (
    <div>
      <h2>Child Data</h2>
      <input type="text" name='name' value={data.name} onChange={handleChange} placeholder={"Name"}/>
      <input type="text" name='title' value={data.title} onChange={handleChange} placeholder={"Title"}/>
      <input type="number" name='phone' value={data.phone} onChange={handleChange} placeholder={"Phone number"}/>

    </div>
  )
}

By the way you also forgot to bind value on the fields so changes in the state from somewhere other than typing in the box wouldn't have been reflected. I've fixed that too.

Additionally what you are doing looks like a code smell. You generally don't want to duplicate state in two places. Instead, you should have one canonical truth. What is the point in the copy that exists in child if you can just pass it back down from the parent?

adsy
  • 8,531
  • 2
  • 20
  • 31