Skip to content

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

A component crashes with Too many re-renders, or the console fills with Maximum update depth exceeded and the page can freeze. Both mean a state update keeps triggering another render, which triggers the update again. The cause is often a single line. Here is what React’s docs say about the loop, where to look, and the fix, or hand it over at a fixed price.

Short answer

Something sets state on every render. The most common cause is onClick={handleClick()}, which calls the function during render instead of passing it. Write onClick={handleClick} or onClick={() => handleClick(id)}. If the loop runs through useEffect, the Effect sets state that changes its own dependencies: remove the Effect, depend on a primitive value instead of an object, or keep the value in a ref.

What sets state on every render, and the fix

  1. 01

    A set function called directly while rendering

    “Typically, this means that you're unconditionally setting state during render, so your component enters a loop” React, useState: Troubleshooting

    React throws Too many re-renders when a component calls a set function in its body with no condition. Each call schedules another render, and that render calls it again. Move the update into an event handler or an Effect, or compute the value during render without storing it in state.

  2. 02

    onClick={handleClick()} instead of onClick={handleClick}

    “Very often, this is caused by a mistake in specifying an event handler” React, useState: Troubleshooting

    The parentheses call the handler while React renders the button, and if the handler sets state, that starts the loop. Pass the function itself, or wrap it in an arrow function when it needs an argument:

    // loops: calls the handler during render
    <button onClick={handleClick()}>Save</button>
    
    // works
    <button onClick={handleClick}>Save</button>
    <button onClick={() => handleClick(id)}>Save</button>
  3. 03

    An Effect that updates its own dependency

    “That state leads to a re-render, which causes the Effect's dependencies to change.” React, useEffect: Troubleshooting

    When the loop goes through useEffect, React’s development build usually warns Maximum update depth exceeded instead. The Effect sets state, the new state changes a value in its dependency array, so it runs again. A common version is an object or array created during render in the dependency list: it is new on every render. Depend on the primitive values inside it, move it into the Effect, or remove the Effect if it only derives data from props or state.

    // loops: filters is a new object on every render
    const filters = { status };
    useEffect(() => {
      setRows(applyFilters(data, filters));
    }, [data, filters]);
    
    // works: no Effect, compute during render
    const rows = applyFilters(data, { status });
  4. 04

    A value that does not need to cause a render

    “If you need to keep track of some data that isn't used by rendering, a ref (which doesn't trigger re-renders) might be more appropriate.” React, useEffect: Troubleshooting

    Counters, timers, previous values and flags that the screen never shows do not belong in state. Keep them in useRef: changing a ref does not render the component again, so it cannot start a loop.

Checked against the vendor’s docs on : React docs: useState, “Too many re-renders”; React docs: useEffect, an Effect re-running in an infinite cycle.

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Next.js hydration error · Next.js “window is not defined” · React Native “Text strings must be rendered within <Text>”

Questions

More on this error

How do I find which component is looping?

Open the error in the browser console and expand its stack trace. Click the arrow next to it and look through the stack for the set function call named there. The component that contains that call is the one looping. React DevTools can also highlight components as they render.

Is Maximum update depth exceeded the same problem?

Yes, the same kind of loop. It usually comes from an Effect, or a class lifecycle method, that sets state on every update. The fixes are the same: stop the update from running on every render.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. 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.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.