React
setState
Good read: https://chatgpt.com/share/79fab4bb-a4a9-4a58-8e55-51d216369c16
React's state update is asynchronous, most of the time it is fine but sometimes it creates some headache due its asynchronous + batching behavior
setState generally has 2 phases: State update & Re-render
When we call setState -> Schedule State Update in the [[Event Loop#^f7064a | Task Queue]] and mark the component as dirty
- All these queued State Update will be batched and execute in 1 [[Event Loop#^f7064a | Event Loop]]
- After executing the batched State Update, it will schedule the Re-render (also in the [[Event Loop#^f7064a | Task Queue]]) to be picked up by the next available iteration of the [[Event Loop#^f7064a | Event Loop]]
setState has 2 form: functional & non-functional
There's no change in scheduling mechanism between 2 forms
When using functional form (updater function), it guarantees to receive the most updated state (event with batching) as the state will be applied sequentially
setState(prevState => ({ count: prevState.count + 1 })); // First call
setState(prevState => ({ count: prevState.count + 1 })); // Second call
When both of these
setState
calls are batched:- React doesn’t execute them immediately.
- It first processes the first updater function:
prevState.count
is the currentcount
value (say,count = 0
), so it calculatescount + 1 = 1
and updates the state to{ count: 1 }
.
- It then processes the second updater function:
- This time,
prevState.count
is 1 (the result of the first updater), so it calculatescount + 1 = 2
and updates the state to{ count: 2 }
.
- This time,
At the end of the batch, React will have updated the state correctly, and only one re-render will happen with the new state
{ count: 2 }
.When you use non-functional
setState
calls (e.g.,setState({ count: 1 })
), React simply overwrites the state with the new object. But, if multiplesetState
calls occur in the same event, React can batch these updates as well. In this case, the last update wins, and intermediate updates may be lost if they occur before the batch is processed.
setState({ count: 1 }); // Direct update
setState({ count: 2 }); // Overwrites previous update
- In this case, React will batch these, and only the last state
{ count: 2 }
is applied, resulting in one re-render withcount = 2
.