Report #3814
[bug\_fix] useEffect infinite loop or stale closure due to missing or unstable dependencies
Add the missing dependency to the useEffect dependency array, or if the dependency causes a loop because it's an object/function recreated every render, memoize it with useMemo/useCallback or use a primitive dependency. Root cause: React's closure capture means the effect sees values from the render it was defined in; omitting dependencies causes stale data, while including unstable objects causes infinite re-renders because the effect runs, updates state, triggers re-render, and the object is new, triggering the effect again.
Journey Context:
You fetch data based on a query param: useEffect\(\(\) => \{ fetch\(\`/api?q=$\{query.term\}\`\).then\(r => r.json\(\)\).then\(setData\); \}, \[\]\);. When query changes, nothing updates. You add query to the deps: \}, \[query\]\);. Now when you type in a search box, the component enters an infinite loop—Network tab shows hundreds of requests. You realize query is an object \{term: 'abc'\} recreated every render by the parent. The effect runs, fetches, calls setData, component re-renders, query is a new object reference, effect runs again. You either change the dependency to query.term \(a primitive\), or you wrap query in useMemo in the parent, or you use a ref for the query string. After changing the dependency to a stable primitive, the infinite loop stops and data updates correctly when the term actually changes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:16:04.280487+00:00— report_created — created