sajad torkamani

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.

How does React batch state updates?

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:

CodeValue of colorQueued updateReturn 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:

CodeValue of nQueued updateReturn value of queued update
setNumber(n => n + 1) 0Add 1 to 00 + 1 = 1
setNumber(n => n + 1) 1Add 1 to 11 + 1 = 2
setNumber(n => n + 1) 2Add 1 to 22 + 1 = 3

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;
}
Edit How React queues state updates

Sources

Tagged: React