-2

With the code below - handleChange methos is used in form fields:

  1. starting i = 0
  2. with the first change
  3. i should get updated with i+1
  4. and console.log(i) = should be 1, but get 0
  • I tried to research the lifecycles and read a lot of posts, but couldn't understand how to fix it (tried to simplify the question).

Thanks

const [i, setI] = useState(0)

const handleChange = input => event => {
        setI(i + 1)
        console.log(i)
        }

<ChildFormComponent handleChange={handleChange}/>
Dennis Kozevnikoff
  • 2,078
  • 3
  • 19
  • 29
  • Step #3 is wrong "i should get updated with i+1". It would be updated after the handler is already finished. You are logging current value of `i`. If you did `setI(i++)` you'd actually update the value though it is **not** recommended way in react. – Yury Tarabanko Jul 14 '20 at 19:53
  • 2
    Also since your state depends on the previous state value recommended way would be to use a callback form `setIt(i => i + 1)` – Yury Tarabanko Jul 14 '20 at 19:55
  • I'm trying to calculate `total_cost` and display it to the user - what's the right way to set something like that to update and then display the updated result? I tried to update now to `setI(i => i + 1)` and it's still showing 0 after first change – Eliran Nider Jul 14 '20 at 19:57
  • State is updated after re-render. See this article for an explanation https://jonathanmadelaine.com/blog/state-it-dont-mutate-it – JMadelaine Jul 14 '20 at 20:00
  • 1
    " I tried to update now to `setI(i => i + 1)` and it's still showing 0" yes because this is how state update works. I though this form would actually make it more clear to you why state updates are async. :) – Yury Tarabanko Jul 14 '20 at 20:02
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Emile Bergeron Jul 14 '20 at 20:08
  • 1
    Thank you all, with all your help it clarified it - I needed to add the useEffect conditionally to the value, as suggested. I appreciate it! – Eliran Nider Jul 14 '20 at 20:12

2 Answers2

3

The setI function is async. I is not updated synchronously but asynchronously. If you want to log the new value of i use the useEffect hook and add i as its dependency.

React.useEffect(() => {
  console.log(i)
}, [i])
Dharman
  • 30,962
  • 25
  • 85
  • 135
Rodrigo Ehlers
  • 1,830
  • 11
  • 25
0

Are you sure on your handleChange declaration? Should it return function to you?

const handleChange = input => event => {
  setI(i + 1)
  console.log(i)
}

Could you try something similar to this instead


const handleChange = event => {
  setI(i => i + 1)
}

And don't worry about console.log(i) since the state updates are asynchronous.

You will get updated data in UI as others suggested in comments.

Prathap Reddy
  • 1,688
  • 2
  • 6
  • 18