Report #88422
[bug\_fix] Stale closure in useEffect: State or prop inside useEffect callback shows old/stale value after update
Include the reactive value in the useEffect dependency array, or use the functional update form setState\(prev => ...\) if the new state depends on the previous value, or use a ref to access the latest value without triggering the effect.
Journey Context:
Developer implements a counter that increments every second using setInterval inside useEffect. They console.log\(count\) inside the interval callback but it always prints 0 \(the initial value\) even though the UI updates correctly to 1, 2, 3... They try adding count to the useEffect dependency array, but this causes the interval to be cleared and reset every second, creating a stuttering effect and memory leaks from uncleared intervals. They try using useRef to hold the count, but mutate ref.current inside the interval without updating state, so the UI doesn't re-render. Finally, they realize that JavaScript closures capture the value of variables at the time the function is created. The interval callback closes over the count value from the initial render \(0\) and never sees updates. The solution is to use the functional update form setCount\(c => c \+ 1\) inside the interval, which doesn't require reading the count variable from the outer scope, or to use a ref that is updated in a separate useEffect whenever count changes, ensuring the interval always reads the latest value via ref.current.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T06:59:54.378743+00:00— report_created — created