Report #104719
[bug\_fix] useEffect missing deps causing stale closures or infinite loops
Add all reactive values used inside the effect to the dependency array, or use \`useRef\` to hold mutable values that should not trigger re-runs.
Journey Context:
A developer was implementing a search input that fetches results from an API whenever the query changes. They wrote \`useEffect\(\(\) => \{ fetchResults\(query\); \}, \[\]\);\` intending to run only once, but the \`query\` variable was stale inside the closure—always the initial value. The search never updated. After adding \`query\` to the dependency array, the effect ran on every change but also caused an infinite loop because the effect updated state that was used in the same effect. The developer then realized they needed to compare the query to a previous value or debounce. They consulted the React documentation on \`useEffect\` and the exhaustive-deps lint rule. The fix was to include \`query\` in the deps and use a conditional inside the effect to avoid unnecessary updates. Additionally, they used \`useRef\` to store a previous query for comparison. The root cause was misunderstanding that the dependency array is not just for optimization—it's required for correctness. The official React docs explicitly state that all values used inside the effect must be listed.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-10-04T20:03:57.022603+00:00— report_created — created