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
// ✅ CountersetCount(prev => prev + 1);
// ✅ TogglesetOpen(prev => !prev);
// ✅ Add to arraysetItems(prev => [...prev, newItem]);
// ✅ Update objectsetUser(prev => ({ ...prev, name: "John" }));Direct value is fine when:
- Setting to a completely new value
javascript
1234
// ✅ These are finesetName("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.