0

I have a function open() in a child component which calls the parent's function open() through props, and it could be multiple times in a row.

the parent function contains this line

this.setState({numOpen: (++this.state.numOpen)});

This line works and updates the state at every increment.

But before, this line

this.setState({numOpen: (this.state.numOpen + 1)});

skipped over several increments and was breaking the program.

Does setState get called asynchronously? if not, what could be the reason for it?

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
M Luffy
  • 33
  • 1
  • 1
  • 4
  • 1
    check this: https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately – Mayank Shukla Jun 12 '17 at 06:34
  • this a good article https://medium.com/@mweststrate/3-reasons-why-i-stopped-using-react-setstate-ab73fc67a42e – Vikram Saini Jun 12 '17 at 06:35
  • 1
    thanks @MayankShukla that answered my question – M Luffy Jun 12 '17 at 06:37
  • 3
    Possible duplicate of [Why calling setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately) – mleko Jun 12 '17 at 06:38
  • @VikramSaini that's a great article, thanks – M Luffy Jun 12 '17 at 06:38

1 Answers1

4

As the Duplicate answer by @MayankShukla indicates, setState is asynchronous,

however Adding an explanation and a corrected approach

In the below case:

this.setState({numOpen: (++this.state.numOpen)});

You are mutating the state directly and then setting the value and hence it works, but is not the right way to do it

In the second case

this.setState({numOpen: (this.state.numOpen + 1)});

setState is adding the value to the current state as you experience it leads to unexpected behaviour due to its asynchronous nature.

The correct way to do it is to use the prevState callback approach

 this.setState((prevState) => ({numOpen: (prevState.numOpen + 1)});
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400