// You call setCount but count still shows the old value
const [count, setCount] = useState(0);
setCount(count + 1);
console.log(count); // Still 0!
State updates in React are asynchronous. The new value isn’t available until the next render.
Fix 1: State Updates Are Async
// ❌ Reading state immediately after setting it
setCount(count + 1);
console.log(count); // Still old value
// ✅ Use useEffect to react to changes
useEffect(() => {
console.log('Count changed:', count);
}, [count]);
Fix 2: Multiple Updates Use Stale Value
// ❌ Both use the same stale count
setCount(count + 1);
setCount(count + 1); // Still adds 1, not 2
// ✅ Use functional update
setCount(prev => prev + 1);
setCount(prev => prev + 1); // Now adds 2
Fix 3: Stale Closure in Event Handler
// ❌ setTimeout captures old value
function handleClick() {
setTimeout(() => {
setCount(count + 1); // Uses count from when handler was created
}, 1000);
}
// ✅ Use functional update
function handleClick() {
setTimeout(() => {
setCount(prev => prev + 1); // Always uses latest
}, 1000);
}
Fix 4: Object/Array State Not Updating
// ❌ Mutating state directly
const [user, setUser] = useState({ name: 'Alice' });
user.name = 'Bob';
setUser(user); // 💥 Same reference — React doesn't re-render
// ✅ Create a new object
setUser({ ...user, name: 'Bob' });
// ✅ Array: create new array
setItems([...items, newItem]);
setItems(items.filter(i => i.id !== id));
Fix 5: useRef for Latest Value
// ✅ When you need the latest value in callbacks
const countRef = useRef(count);
countRef.current = count;
function handleClick() {
setTimeout(() => {
console.log(countRef.current); // Always latest
}, 1000);
}