🔧 Error Fixes
· 1 min read

React useState Not Updating — How to Fix Stale State


// 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);
}
📘