Why are multiple setState placed in timers in react not merged and executed again?

description

setState updates state through a queue mechanism. When setState is executed, the state that needs to be updated will be merged and put into the status queue, instead of updating this.state immediately. The queue mechanism can update state in batches efficiently.

example:

constructor(){
    this.state={
        val:0,
    }
}
componentDidMount(){
    this.setState({val:this.state.val+1});
    console.log(this.state.val);
    
    this.setState({val:this.state.val+1});
    console.log(this.state.val);
    
    setTimeout(()=>{
    this.setState({val:this.state.val+1});
    console.log(this.state.val);
    
    this.setState({val:this.state.val+1});
    console.log(this.state.val);
    },0);
}
result: 0re0pence2penny 3

problem description

Why not 0pl 0pl 2jol 2?

  • 0re0jue 2 can understand that the first two updates are still in batch, so merge setState, first and get the result only the next time render.
  • when setTimeout is executed, the first setState is updated to false, in batches at this time, but why does this setState not change the component state to batch update status? This triggers the batch update transaction and causes the two setState in the timer to merge?

is very confusing, the feeling contradicts with the explained setState mechanism, but the result is executed separately.


  1. setState is "asynchronous" only in composite events and hook functions, and Synchronize in both native events and setTimeout .
  2. The "async" of setState does not mean that it is internally implemented by asynchronous code. In fact, the process and code executed by itself are Synchronize, but the calling order of composite events and hook functions is before the update, so that the updated values cannot be obtained immediately in the composite events and hook functions, in the form of so-called "asynchrony". Of course, you can get the updated results through callback in the second parameter setState (partialState, callback) .
  3. The batch update optimization of setState is also based on "asynchronous" (synthetic events, hook functions). There are no batch updates in native events and setTimeout . If the same value is updated multiple times setState in "async", the batch update strategy of setState will overwrite it and take the last execution. If it is multiple different values at the same time setState , batch updates will be merged.
MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1b3b618-2bae0.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1b3b618-2bae0.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?