Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

Next.js · updated 2026-11-04

Thrown by React when a component updates state while rendering and the updates never settle. It shows up in Client Components in Next.js and any React app, usually right after a component mounts.

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
    at renderWithHooksAgain (react-dom-client.development.js:5629:17)
    at renderWithHooks (react-dom-client.development.js:5541:22)
    at Filters (./src/components/Filters.tsx:12:5)

Quick fix

Look for a state setter that runs during render. The usual one is onClick={setOpen(true)} (a call) instead of onClick={() => setOpen(true)} (a function). Otherwise, move derived values into a plain variable or useMemo, and side-effect updates into useEffect.

  1. Open the component named in the trace and find every setX( call outside handlers and effects.
  2. Change onClick={setX(value)} to onClick={() => setX(value)}.
  3. If a value can be computed from props or state, compute it during render instead of storing it with setState.
  4. If state must follow a prop, update it in useEffect (or use a key to reset the component), not in the render body.
typescript
'use client';
import { useMemo, useState } from 'react';

export function Filters({ items }: { items: Item[] }) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');

  // Before: const [visible, setVisible] = useState([]); setVisible(items.filter(...));  (runs every render)
  const visible = useMemo(() => items.filter((i) => i.name.includes(query)), [items, query]);

  return (
    <>
      <button onClick={() => setOpen(!open)}>Filters</button>  {/* not onClick={setOpen(!open)} */}
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <List items={visible} />
    </>
  );
}

Why it happens

Calling a setter instead of passing a function

onClick={setCount(count + 1)} runs setCount during render; React re-renders, runs it again, and so on. The arrow function only runs on click.

Syncing derived state in the render body

Calling setFiltered(items.filter(...)) directly in the component body updates state on every render. Derived values belong in a variable or useMemo.

Setting state from props without a guard

Copying a prop into state on every render (if (prop !== state) setState(prop) without a stable comparison) can loop when the prop is a new object each time.

Other fixes

  • An effect that sets state and lists that state in its dependencies loops too, but shows "Maximum update depth exceeded" instead.
  • React DevTools highlights which component keeps rendering if the trace is not clear.

Same error, other wording

  • Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.
  • Warning: Cannot update a component while rendering a different component.

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the 'Too many re-renders' errors, open the components named in the traces, and fix each state update that runs during render (setter calls in JSX props, derived state set in the body).

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: React docs: state as a snapshot and setState during render, React docs: you might not need an effect (derived state)