Short answer
Find the useEffect (or componentDidUpdate) that calls a setter. If it has no dependency array, it runs after every render: add one. If a dependency is an object, array or function created during render, it is new every time: depend on a primitive value instead, move it inside the effect, or memoize it. If the state can be computed from props or other state, delete the effect and calculate it during render. In a class component, onClick={this.setState({ open: true })} runs during render and loops the same way: pass a function instead. (In a function component, onClick={setOpen(true)} gives "Too many re-renders" instead.)
Why the updates never stop, and the fix
01
An effect sets state and has no dependency array
“If you omit this argument, your Effect will re-run after every commit of the component.” React, useEffect
Without the second argument, the effect runs after every render. If it sets state, that state causes a render, which runs the effect again. Add the dependency array with only the values the effect really reads.
// 🔴 runs after every render, sets new state each time, loops useEffect(() => { setVisible(items.filter((i) => !i.done)); }); // ✅ runs only when items changes useEffect(() => { setVisible(items.filter((i) => !i.done)); }, [items]);02
A dependency is a new object or function each render
“If some of your dependencies are objects or functions defined inside the component, there is a risk that they will cause the Effect to re-run more often than needed.” React, useEffect
An object, array or function written inside the component is a new value on every render, so an effect that depends on it runs every time. If that effect sets state, it loops. Depend on the primitive values you need, create the object inside the effect, or wrap it in useMemo or useCallback as a last resort. The same happens with a store selector that returns a new object each render (useStore((s) => ({ a: s.a, b: s.b })) in Zustand 5): select single values or use a shallow comparison.
// 🔴 options is new each render const options = { roomId }; useEffect(() => { connect(options); setAttempts((n) => n + 1); }, [options]); // ✅ depend on the value itself useEffect(() => { connect({ roomId }); setAttempts((n) => n + 1); }, [roomId]);03
The effect updates a value it also depends on
“Your Effect is updating some state. That state leads to a re-render, which causes the Effect’s dependencies to change.” React, useEffect: My Effect keeps re-running in an infinite cycle
An effect that reads count and sets count, with count in its dependencies, triggers itself. Use the updater form so the effect does not need the value, or ask whether the effect is needed at all: values that can be computed from props or state belong in the render, not in an effect.
// ✅ computed during render, no effect, no loop const visibleTodos = todos.filter((t) => !t.done);04
A setState during render or in componentDidUpdate
In a class component, onClick={this.setState({ open: true })} calls setState while rendering instead of on click; pass onClick={() => this.setState({ open: true })}. (In a function component, onClick={setOpen(true)} gives “Too many re-renders”, covered on the linked page.) setState in componentDidUpdate without comparing to the previous props or state loops the same way: wrap it in a condition.
componentDidUpdate(prevProps) { if (prevProps.userId !== this.props.userId) { this.setState({ user: null }); } }
Checked against the vendor’s docs on : React: useEffect (dependencies and the infinite cycle troubleshooting section).
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: React “Too many re-renders” · React “Invalid hook call” · Next.js hydration error