ShaharAmir
← Back to Blog
React2 min read

Why Your setState Isn't Working

Use the callback form when your next state depends on the previous state

S
Shahar Amir

Why Your setState Isn't Working

Ever clicked a button twice fast and the count only went up once?

javascript
123456
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1); // Still 1, not 2!
};

This is a classic React gotcha.

The Problem

State updates are batched and asynchronous. Both setCount calls see the same count value (0), so you get 1, not 2.

The Fix: Callback Form

javascript
1234
const handleClick = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1); // Now it's 2!
};

The callback receives the latest state, not the stale closure value.

When to Use the Callback

Use callback when:

  • Next state depends on previous state
  • Multiple updates in same handler
  • Updates inside intervals/timeouts

javascript
1234567891011
// ✅ Counter
setCount(prev => prev + 1);
// ✅ Toggle
setOpen(prev => !prev);
// ✅ Add to array
setItems(prev => [...prev, newItem]);
// ✅ Update object
setUser(prev => ({ ...prev, name: "John" }));

Direct value is fine when:

  • Setting to a completely new value

javascript
1234
// ✅ These are fine
setName("John");
setItems([]);
setUser(null);

Rule of Thumb

If you see setSomething(something + ...), use setSomething(prev => prev + ...) instead.

Your future self debugging race conditions will thank you.

#hooks#useState#state

Stay Updated 📬

Get the latest tips and tutorials delivered to your inbox. No spam, unsubscribe anytime.