Report #76072
[bug\_fix] Maximum update depth exceeded or stale closure in useEffect causing infinite re-renders
Ensure all values used inside useEffect are listed in the dependency array. For objects or arrays, memoize them with useMemo or define them outside the component. For functions, use useCallback. If the effect updates state that it also depends on, use functional state updates or move logic to an event handler. Root cause: JavaScript closures capture values at the time of render; if dependencies aren't tracked correctly, the effect operates on stale data or triggers itself infinitely when object references change.
Journey Context:
Developer writes a useEffect that calls setCount\(count \+ 1\) whenever count changes, creating an obvious infinite loop. More subtly, they pass an object const config = \{ threshold: 10 \} defined inside the component into the effect's dependency array. Because a new object is created every render, the effect fires continuously. The React DevTools Profiler shows rapid re-renders. The developer tries to remove the dependency from the array to stop the loop, but then the effect uses a stale value of a prop from a previous render. They read the React docs on the Rules of Hooks and the exhaustive-deps ESLint rule. They learn to use useMemo for the config object or to move it outside the component. For the count case, they change to setCount\(c => c \+ 1\) and remove count from deps, or move the logic to an onClick handler instead of an effect.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T10:16:47.800003+00:00— report_created — created