Report #4617
[bug\_fix] Maximum update depth exceeded. This can happen when a component calls setState inside useEffect or useLayoutEffect in a way that causes an infinite loop
Stabilize the dependency array values to have referential equality across renders. If the effect depends on an object or array, wrap its creation in useMemo so the same instance is reused unless contents change. Alternatively, use a primitive dependency \(like a string ID\) instead of the whole object, or move the object creation inside the effect if it isn't used elsewhere. Root cause: Object and array literals create new references every render; when passed as dependencies to useEffect, React sees a changed dependency, runs the effect, which calls setState, triggering a re-render that creates new object references again, causing an infinite loop.
Journey Context:
Developer creates a dashboard component that fetches user stats. They define a filters object: const filters = \{ status: 'active', type: selectedType \}. They use this in useEffect: useEffect\(\(\) => \{ fetchStats\(filters\).then\(setData\) \}, \[filters\]\). Initially it works, but as soon as selectedType changes or any parent state updates, the component enters an infinite re-render loop, browser freezes, and React throws 'Maximum update depth exceeded'. Developer checks the dependency array and sees 'filters', thinking it's stable. They try adding console.logs and realize the effect runs, updates state, triggers render, and filters is a new object literal every time. They refactor to use useMemo\(\(\) => \(\{ status: 'active', type: selectedType \}\), \[selectedType\]\) for filters, breaking the infinite loop.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T19:47:39.647270+00:00— report_created — created