React setState is a special function used by React to manage state. We use it a lot in React.

export class Todo extends React.Component{... increaseScore () {this.setState({count : this.state.count + 1});
    this.setState({count : this.state.count + 1}); }... }Copy the code

In this code, increaseScore increasesthe count state by one, but if you do the increaseScore on the console, you’ll find that it’s only increased by one!

Why is that?

SetState is asynchronous

SetState is asynchronous

Look at this example

class BadCounter extends React.Component{
  constructor(props){
    super(props);
    this.state = {count : 0} 
  }
  incrementCount=(a)= >{
    this.setState({count : this.state.count + 1}) 
    this.setState({count : this.state.count + 1})
  }
  render(){
    return <div>
              <button onClick={this.incrementCount}>+ 2</button>
              <div>{this.state.count}</div>
          </div>}}class GoodCounter extends React.Component{
  constructor(props){
    super(props);
    this.state = {count : 0} 
  }
  incrementCount=(a)= >{
   this.setState((prevState, props) = > ({
      count: prevState.count + 1
    }));
   this.setState((prevState, props) = > ({
      count: prevState.count + 1
    }));
  }
  render(){
    return <div>
              <button onClick={this.incrementCount}>+ 2</button>
              <div>{this.state.count}</div>
          </div>}}Copy the code

In this demo, both the upper and lower counters are supposed to be +2, but the actual effect is as follows. Only the second counter meets our expectations:

Using the code, we can see that the difference between the two counters passes different arguments to setState

// In the error example
this.setState({count : this.state.count + 1}) 
this.setState({count : this.state.count + 1}) 

// In the correct example
this.setState((prevState, props) = > ({
  count: prevState.count + 1
}))
this.setState((prevState, props) = > ({
  count: prevState.count + 1
}))
Copy the code

A review of the data shows that when setState () is called multiple times, React does not process these setState () functions synchronously. Instead, it does a “batch process” — if objects are passed as arguments to setState, React merges them.

Similarly, when you pass a function to setState (), those functions are put in a queue and executed in the order they were called.

Here’s React core member Dan Abramov explaining why setState is asynchronous

conclusion

The next time you need to use this.state in setState, remember that using a function to get the last state value is the correct way to do it!