Batching behaviour in React 17
19 September 2022 (Updated 19 September 2022)
Credit: mostly taken from this post.
What is batching?
Batching is when React groups multiple state updates into a single re-render for better performance.
React 17 batched state updates in event handlers
React 17 batches multiple updates inside event handlers by default:
function App() {
const [count, setCount] = useState(0)
const [flag, setFlag] = useState(false)
function handleClick() {
setCount(c => c + 1) // Does not re-render yet
setFlag(f => !f) // Does not re-render yet
// React will only re-render once at the end (that's batching!)
}
return (
<div>
<button onClick={handleClick}>Increment</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
}
Here, React will wait until handleClick
finishes execution before it processes the state updates. As a result, handleClick
will only trigger a single re-render.
React 17 did not batch state updates outside event handlers
Although React 17 batches state updates inside React events like onClick
, it didn’t batch updates inside promises, setTimeout
, setInterval
or other native browser events:
function App() {
const [count, setCount] = useState(0)
const [flag, setFlag] = useState(false)
function handleClick() {
fetchSomething().then(() => {
// React 17 and earlier does NOT batch these because
// they run *after* the event in a callback, not *during* it
setCount(c => c + 1) // Causes a re-render
setFlag(f => !f) // Causes a re-render
});
}
return (
<div>
<button onClick={handleClick}>Increment</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
)
}
Here, the callback to fetchSomething
will cause two re-renders – one after setCount(c => c + 1)
, one after setFlag(f => !f)
.
Sources
Tagged:
React
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment