Updater Functions

`setX(prev => prev + 1)` Reads the Latest Value

Updater Functions

When the next state depends on the previous state, pass a function to the setter. React calls it with the latest state.

3 min read Level 2/5 #react#state#updater
What you'll learn
  • Use the updater form to base new state on previous state
  • Stack multiple updates in one event correctly

When the next state depends on the previous state, pass a function instead of a value. React calls it with the latest queued state.

The Two Forms

// Direct value — based on this render's snapshot
setCount(count + 1);

// Updater function — based on the latest queued state
setCount(prev => prev + 1);

When the Difference Matters

function handleClick() {
  setCount(count + 1);  // count is 0 → schedule 1
  setCount(count + 1);  // count is still 0 → schedule 1
  setCount(count + 1);  // count is still 0 → schedule 1
}
// Final: 1

vs.

function handleClick() {
  setCount(prev => prev + 1);  // schedule (prev => prev + 1)
  setCount(prev => prev + 1);  // schedule again
  setCount(prev => prev + 1);  // and again
}
// React runs them in order: 0 → 1 → 2 → 3. Final: 3

The updater form sees the latest queued value, not the snapshot from the render where the click happened.

Rule of Thumb

If the new state references the current state — increment, append, toggle — use the updater form. Otherwise either form is fine.

PatternUse updater?
setCount(prev => prev + 1)Yes
setItems(prev => [...prev, item])Yes
setOpen(prev => !prev)Yes
setName("Ada")Direct (no prev)
setUser(newUser)Direct

Updater + Objects

For object state, the updater takes the previous object:

const [user, setUser] = useState({ name: "Ada", count: 0 });

function increment() {
  setUser(prev => ({ ...prev, count: prev.count + 1 }));
}

The Updater Should Be Pure

It’s a function — keep it free of side effects. Don’t read other state, don’t fetch, don’t log. Just compute the next value.

Up Next

If several setX calls happen in one event, React batches them into a single re-render.

Batching →