Report #61717
[bug\_fix] Maximum update depth exceeded \(infinite loop\) in useEffect
Use a functional update for state if the new value depends on the old one, or memoize the dependency using \`useMemo\` to keep object references stable, or use a primitive dependency \(like an ID\) instead of the whole object/array.
Journey Context:
A developer writes a filter component that fetches posts whenever the filter criteria change. They write: \`useEffect\(\(\) => \{ fetchPosts\(filter\).then\(setPosts\); \}, \[filter\]\);\` where \`filter\` is an object defined in the component body: \`const filter = \{ category, status \}\`. Because \`filter\` is a new object literal on every render, the effect runs after every render, calling \`setPosts\`, which triggers a re-render, creating a new \`filter\` object again. The browser tab freezes and the console shows "Maximum update depth exceeded." The developer first tries adding \`eslint-disable-line\` to the dependency array, which only hides the warning. They then try to spread the object into primitive deps: \`\[filter.category, filter.status\]\`, which fixes it because primitives are compared by value. Alternatively, they could wrap \`filter\` in \`useMemo\` so the object reference is stable unless the contents change. The loop stops because the effect now only runs when the actual values change, not on every reference change.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T10:04:55.427554+00:00— report_created — created