Code:
useEffect(() => {
setTimeout(() => {
// this cause re-render twice
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
}, 1000);
}, []);
My question is why this component re-render twice if we call two setCount
in sequence.
Doesn't React batch multiple setCount
in one go?
Thank you for answering or any suggestion.
codesandbox example
EDIT (2023): React 18 has changed this behavior and now even this case will be batched.
Original answer (2020):
Doesn't React batch multiple setCount in one go?
It does if it can. This is a case where it can not.
In order for react to batch things, the execution of code needs to start within react itself. For example, any component lifecycle events, or any synthetic event callbacks (eg, the onClick
for a <button>
). When that happens, react can let your code keep running, queuing up as many set states as you like, and then once your done you will return to react's code, which can then render the queued changes.
But if code execution did not start from react, then once you return, you're not going to be returning to react's code. So since they won't get to run code after yours, they do the render right away.
The other answers explained why it is rendering several times.
Now, I want to give a solution to make it render only once. There is an API that allows you to make only one render: ReactDOM.unstable_batchedUpdates
In your example:
ReactDOM.unstable_batchedUpdates(() => {
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
});
}, 1000);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With