Report #91570
[bug\_fix] Maximum update depth exceeded \(React error \#185\) caused by useEffect running in an infinite loop due to object or array dependencies
Use primitive values \(strings, numbers, booleans\) in the dependency array, or memoize the object using useMemo with a stable dependency list, or move the object creation inside the useEffect itself. Root cause: React uses Object.is comparison for dependencies. A new object or array literal created during render \(\{\}\) is a new reference every render, triggering the effect, which calls setState, which re-renders, creating a new reference again.
Journey Context:
Developer writes a useEffect to fetch data when filters change: useEffect\(\(\) => \{ fetchData\(filters\); \}, \[filters\]\). The filters variable is defined in the component as const filters = \{ status: 'active', type: 'user' \}. On loading the page, the browser freezes or shows the 'Maximum update depth exceeded' error with a stack trace pointing to the useEffect. Developer adds console.log inside the effect and sees it running hundreds of times in a loop. They suspect a closure issue or stale dependencies. They try adding a cleanup function, but the loop continues. They read the React docs on useEffect troubleshooting and find the section on infinite cycles. They learn that objects are compared by reference, not by value. They realize that \`filters\` is a new object on every render. They refactor the effect to depend on primitive values: \[filters.status, filters.type\]. Alternatively, they wrap filters in useMemo: const filters = useMemo\(\(\) => \(\{ status, type \}\), \[status, type\]\). The infinite loop stops immediately. They understand that dependency arrays must contain stable references.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T12:17:33.370359+00:00— report_created — created