How does React batch state updates?
In a nutshell
Just as a restaurant waiter waits until a customer has finished their order before passing the order to the kitchen, React only processes state updates after event handlers have finished running.
For example, in the following handleClick
handler, React will wait until all the statements (orders) in handleClick
have been executed before it updates the color
state and triggers a re-render (passes the order to the kitchen). This means the handleClick
function will only cause a single state update and therefore a single re-render.
function App() {
const [color, setColor] = useState('')
function handleClick() {
setColor('orange')
setColor('pink')
setColor('blue')
}
return (
<>
<p>Color: {color}</p>
<button onClick={handleClick}>Change color</button>
</>
)
}
The state update triggers a re-render and during rendering, React will walk through the state update queue for color
to figure out what its final value should be:
Code | Value of color | Queued update | Return value of queued update |
setColor('orange') | '' (unused) | “Replace with 'orange' “ | 'orange' |
setColor('pink') | 'orange' (unused) | “Replace with 'pink' “ | 'pink' |
setColor('blue') | 'pink' (unused) | “Replace with 'blue' “ | 'blue' |
Despite multiple setColor
statements, the handleClick
function causes a single re-render, and in that re-render, the color
state will be set to 'blue'
– the result of the queued updates.
Update same state variable multiple times before next render
This is a less common use case, but if for whatever reason, you wanted to update the same state variable multiple times before the next render, you can use a state updater function like setNumber(n => n + 1)
.
This means that in the following snippet, the onClick
handler will increment number
by 3
“
function Counter() {
const [number, setNumber] = useState(0)
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(n => n + 1)
setNumber(n => n + 1)
setNumber(n => n + 1)
}}>+3</button>
</>
)
}
Here’s how React batches the setNumber
state updates:
Code | Value of n | Queued update | Return value of queued update |
setNumber(n => n + 1) | 0 | Add 1 to 0 | 0 + 1 = 1 |
| 1 | Add 1 to 1 | 1 + 1 = 2 |
| 2 | Add 1 to 2 |
|
Example implementation of React’s processing of state updates
export function getFinalState(baseState, queue) {
let finalState = baseState;
for (let update of queue) {
if (typeof update === 'function') {
// Apply the updater function.
finalState = update(finalState);
} else {
// Replace the next state.
finalState = update;
}
}
return finalState;
}
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment