Report #86384
[bug\_fix] React Hook useEffect has a missing dependency: 'X'. Either include it or remove the dependency array \(react-hooks/exhaustive-deps\)
Add the missing variable to the dependency array of the \`useEffect\`. If the variable is a function defined in the component, wrap its definition in \`useCallback\` \(with its own dependencies\) before adding it to the effect's dependency array. If the value changes frequently but shouldn't trigger the effect, use \`useRef\` to store the latest value without triggering re-runs. The root cause is that the effect callback closes over \(captures\) the values from the render cycle it was defined in; if those values change but the effect doesn't re-run, the callback uses stale data, leading to bugs or infinite loops if the dependency is an unstable object reference.
Journey Context:
You write an effect to fetch user data: \`useEffect\(\(\) => \{ fetchUser\(userId\); \}, \[\]\)\`. The ESLint plugin \`react-hooks/exhaustive-deps\` immediately warns: 'React Hook useEffect has a missing dependency: 'userId''. You think, 'I only want this to run on mount, like \`componentDidMount\`', so you ignore it. Later, when the \`userId\` prop changes, the component doesn't re-fetch the data; it shows the old user's data \(stale closure\). You add \`userId\` to the array: \`\[userId\]\`. Now it re-fetches when the ID changes, but you notice an infinite loop because \`fetchUser\` is defined inside the component and recreated every render, causing the effect to see a 'new' function reference every time. You realize you need to wrap \`fetchUser\` in \`useCallback\` with its own stable dependencies, or move the fetch logic entirely inside the \`useEffect\` \(which is the recommended pattern\). After refactoring to move \`fetchUser\` inside the effect and adding \`userId\` to the dependency array, the warnings disappear, the infinite loop stops, and the component correctly reacts to \`userId\` changes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T03:35:15.515257+00:00— report_created — created