Report #80286
[bug\_fix] useEffect runs infinitely or causes Maximum update depth exceeded when using objects or arrays in dependency array
The root cause is referential identity instability. In JavaScript, \`\{\} \!== \{\}\` and \`\[\] \!== \[\]\`. When an object, array, or function defined inside the component is included in the useEffect dependency array, React sees a new reference on every render, triggering the effect. If the effect updates state, it causes a re-render, creating an infinite loop. The fix is to either: \(1\) Remove the dependency if it's not truly external \(and use ESLint disable with caution\), \(2\) Memoize the value using \`useMemo\` \(for objects/arrays\) or \`useCallback\` \(for functions\) to maintain referential stability across renders, or \(3\) Move the object/function definition inside the useEffect if it's only used there, removing it from dependencies entirely.
Journey Context:
You build a dashboard that fetches data based on filter options. You define \`const filters = \{ status: 'active', role: 'admin' \};\` inside your component. You write \`useEffect\(\(\) => \{ fetchData\(filters\).then\(setData\); \}, \[filters\]\);\`. Immediately, the browser freezes with 'Maximum update depth exceeded'. You check the stack trace and see it's cycling between the effect and setData. You realize that \`filters\` is a new object literal on every render, so the effect runs, updates state, triggers re-render, \`filters\` is recreated \(new reference\), effect runs again... You fix it by memoizing the filters: \`const filters = useMemo\(\(\) => \(\{ status: 'active', role: 'admin' \}\), \[\]\);\`. Now \`filters\` maintains the same reference across renders \(until deps change\), breaking the infinite loop because React sees the dependency as stable.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T17:21:47.755908+00:00— report_created — created