I need help #86923
-
|
Why does React batch state updates, and when can batching fail? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
React batches state updates to minimize re-renders, improving performance by grouping many changes into a single render and commit cycle. |
Beta Was this translation helpful? Give feedback.
-
|
This is about consistency.
There's a lot of misconceptions regarding batching. Batching is not the reason why you can't like, read an update as you call setState, for example in: const [ counter, setCounter ] = useState(0);
// later in a click handler
setCounter(counter + 1)
console.log(counter)
setCounter(counter + 1)Here we all know by now that this setCounter to exactly, // with counter at 0
setCounter(0 + 1)
console.log(0)
setCounter(0 + 1)That's what you are doing there. Where you can see batching is in cases like: // later in a click handler
if (/* a given condition */) {
setCounter(counter + 1)
}
// later in the same handler
if (/* some other condition */) {
setCounter(counter * 2 + 1)
}At the end of the event handler, the batched updates are simplified into one, and the last relevant one applies. Keeping the application view consistent with your logic. Where you might want to flushSync, is if you also want to show the If there's real interested in this question beyond farming answers for bots: In React 17function App() {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
function handleClick() {
setLoading(true);
fetchSomething().then((result) => {
// React 17 and earlier does NOT batch these because
// they run *after* the event in a callback, not *during* it
setLoading(false) // Causes a re-render
setData(result) // Causes a re-render
});
}
if (loading) return <p>Loading...</p>
return <p>{data?.uuid}</p>
}In React 17, setData and setLoading, would not be batched, so you'd actually see a frame with nothing in the screen, with data In React 18, this was changes, so that now these are batched too! And you don't have that extra frame.
The crash in React 17 and before would be prevented by switching the order of calls: setData(result) // Causes a re-render
setLoading(false) // Causes a re-renderBut that's extremely brittle and not a good pattern to have around... |
Beta Was this translation helpful? Give feedback.
React batches state updates to minimize re-renders, improving performance by grouping many changes into a single render and commit cycle.
Batching keeps renders logically consistent, ensuring components see a stable snapshot of state instead of flickering through intermediate partial changes.
It appears to fail when you read state immediately after calling setState, because updates apply after React finishes rendering later.
Batching can also break with flushSync, separate event or timeout tasks, or older React versions where async events weren’t batched