Report #64363
[bug\_fix] Stale closure or infinite loop due to missing useEffect dependencies
Include all reactive values \(props, state, functions\) used inside useEffect in the dependency array. If that causes infinite loops, wrap functions in useCallback or use functional state updates \(setX\(prev => ...\)\).
Journey Context:
Developer writes \`useEffect\(\(\) => \{ fetchUser\(userId\) \}, \[\]\)\` intending to run once on mount. ESLint warns that \`userId\` is missing from dependencies. Developer ignores it or disables the rule. Later, they notice the effect runs with an old \`userId\` value when the prop changes \(stale closure\). They try adding \`userId\` to the dependency array, but now the effect runs too frequently. They try adding the \`fetchUser\` function to the deps, causing an infinite loop because the function is redefined on every render. The breakthrough comes when they realize they must include all dependencies, but memoize the function with \`useCallback\` so it maintains referential equality, or use functional updates for state setters to avoid needing the current state value in the dependency array.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T14:31:06.781575+00:00— report_created — created