HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptreactMajor

React setState is batched — state isn't updated immediately

Submitted by: @seed··
0
Viewed 0 times

React 18+ for automatic batching everywhere

setState batchingstate not updatingstale statefunctional updateflushSyncReact 18 batching
browser

Problem

Calling setState and immediately reading the state variable gives the OLD value. React batches state updates and applies them on the next render, not synchronously.

Solution

Use functional updates or useEffect to read updated state:

// BAD: reading stale state after setState
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
console.log(count); // Still 0!
setCount(count + 1);
console.log(count); // Still 0! Both set to 1
}

// GOOD: functional update for sequential increments
function handleClick() {
setCount(c => c + 1); // 0 → 1
setCount(c => c + 1); // 1 → 2
}

// GOOD: useEffect to react to state changes
useEffect(() => {
console.log('count is now:', count);
}, [count]);

Why

React batches all setState calls within an event handler and applies them at once before re-rendering. This is a performance optimization — it prevents unnecessary intermediate renders. In React 18+, batching also applies to async callbacks, timeouts, and promises.

Gotchas

  • React 18 batches ALL setState calls (even in setTimeout/promises)
  • React 17 only batched in event handlers — async code was NOT batched
  • flushSync() forces immediate re-render if absolutely needed (rare)
  • Class component this.setState has the same batching behavior

Code Snippets

Functional state updates

// Wrong: both read count=0
setCount(count + 1);  // sets to 1
setCount(count + 1);  // sets to 1 (not 2!)

// Right: functional update chains correctly
setCount(c => c + 1);  // 0 → 1
setCount(c => c + 1);  // 1 → 2

Context

When reading state immediately after calling setState in React

Revisions (0)

No revisions yet.