0

Hi guys I was stuck on a problem with state being behind a click. I'm creating an input where users can type the name of the item they want and the handleChange function would filter the original items array for titles that match whatever is in the input value. I searched up a couple stack overflow questions that were similar to this problem and they suggested console.logging in useEffects but when I do that, it's still one click behind. Any suggestions?

the functionality:

 const handleChange = (e) => {
    const results = []
    setValue(e.target.value)

    for (let item of items) {
      if (item.includes(value)) {
        results.push(item)
      }
    }
    setNewItems(results)
  }


  useEffect(() => {
    console.log(newItems)
  }, [newItems])

the component:

<input
   onChange={handleChange}
   value={value}
/>
  • setValue is `async` so it's not guarantee that the setValue updates the value immediately. so you'd need to do `setValue( prevValue => e.target.value)` – AdityaParab Jul 07 '22 at 18:12
  • 1
    alternatively, you also do `item.includes(e.target.value)` – AdityaParab Jul 07 '22 at 18:12
  • @AdityaParab the first statement might not be correct. Even using the functional pattern of setState does not guarantee that state updates won't be batched. In fact it is only useful when you want to make use of previous state value to determine next state value. – Tushar Shahi Jul 07 '22 at 18:15

2 Answers2

0

Everything is good except the fact that the code tries to access value as soon as it is set. React state updates are batched and both setValue and setItems will be batched and set the state together.

The correct way to access the latest value of value here would be:

if (item.includes(e.target.value))
Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
0

State assigning is asynchronous, meaning that rendering often doesn't line up with assignments.

You might find some answers here.

sid_mac
  • 151
  • 2
  • 10