Blog
3 min read

React "Too Many Re-renders" and "Maximum Update Depth Exceeded": Fixes

Both errors mean a component keeps updating state, which re-renders it, which updates state again — forever. The four patterns that cause it (calling a handler instead of passing it, setState during render, effects without dependencies, objects in dependency arrays) and their fixes.

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Error: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect...

Both errors describe an infinite loop. In React, changing state makes the component render again. If rendering changes state, which makes it render, which changes state… React stops it before your browser tab freezes.

There are four common ways to cause it. Each has a one-line fix.

1. Calling a function instead of passing it

The most common cause by far:

<button onClick={setCount(count + 1)}>+</button>   // ❌

The () calls setCount immediately, during render. That updates state, which re-renders, which calls it again.

You want to pass a function that React will call later, on click:

<button onClick={() => setCount(count + 1)}>+</button>   // ✅

Same for any handler that takes an argument:

<button onClick={handleDelete(item.id)}>Delete</button>         // ❌
<button onClick={() => handleDelete(item.id)}>Delete</button>   // ✅

2. Setting state directly in the component body

function Profile({ user }) {
  const [name, setName] = useState('')
  setName(user.name)   // ❌ runs on every render
  ...
}

Usually you don't need state at all — use the prop directly, or compute the value:

const name = user.name   // ✅

If you genuinely need to reset state when a prop changes, give the component a key so React remounts it: <Profile key={user.id} user={user} />. (useState explained)

3. useEffect with no dependency array

useEffect(() => {
  setItems(fetchedItems)
})   // ❌ no array: runs after every render

An effect with no dependency array runs after every render. If it sets state, that's a loop. Add the array:

useEffect(() => {
  setItems(fetchedItems)
}, [fetchedItems])   // ✅ only when fetchedItems changes

And ask whether you need the effect at all — copying a prop into state inside an effect is usually unnecessary. (useEffect explained)

4. Objects or arrays in the dependency array

This one is sneaky, because the array is there:

const filters = { status: 'active' }   // new object every render

useEffect(() => {
  fetchItems(filters).then(setItems)
}, [filters])   // ❌ "changed" on every render

React compares dependencies by identity. A new object {} is never equal to the last one, even with the same contents. So the effect runs every render, sets state, re-renders, creates a new object…

Fixes:

// depend on the primitive value
useEffect(() => { ... }, [filters.status])

// or create the object once
const filters = useMemo(() => ({ status: 'active' }), [])

The same applies to functions defined in the component and passed as dependencies — wrap them in useCallback or move them inside the effect.

How to find which one it is

  • The error's component stack in the console names the component. Start there.
  • Look for onClick={something( — an opening paren right after the handler name.
  • Look for set...( calls outside of event handlers and effects.
  • Check every useEffect that calls a setter: does it have a dependency array, and does that array contain objects, arrays or functions?

The summary

  • The loop is: state update → render → state update.
  • onClick={fn()} calls it; onClick={() => fn()} passes it.
  • Don't call setters in the component body.
  • Give effects a dependency array, and keep objects and functions out of it (or memoise them).

EasySpawn gives Claude Code your running dev server and browser preview on a persistent machine, so it can reproduce render loops and verify the fix — not just guess at it. See how it works or join the waitlist.

Related: useEffect Explained · useState Explained · What Is React? · Next.js Hydration Errors

Keep reading