Tutorials Logic, IN info@tutorialslogic.com

Too many re renders in React Fix Infinite Loop

What the Error Means

Too many re-renders happens when a component asks React to update state while React is still building that same render. The render call finishes, the setter runs immediately, and the component drops back into the same render path again and again.

The usual culprits are a setter call in JSX, a function call passed where a callback should be passed, or code that writes state during render instead of waiting for an event or effect.

The reliable fix is to move the update into an event handler, stop executing functions during render, or remove state that only mirrors a value already available from props or derived data.

React calls your component to build JSX. If that call triggers a state setter before the render is complete, React has to schedule another render immediately. If the same setter is reached again, the loop continues until React stops it with this error.

This is a render-phase problem. It is not about a slow effect or a missing dependency array. The component is mutating state while it is still describing the UI.

  • The setter runs during render, not after it.
  • The component keeps re-entering the same code path.
  • React blocks the loop before the page becomes unusable.

What Usually Triggers It

The most obvious trigger is a direct setter call inside the component body. The next most common trigger is onClick={setValue(value)} or a similar prop assignment, which executes the setter as the JSX is created instead of waiting for the click.

It also shows up when a render helper, a ternary, or a child prop causes a setter to run as part of building the tree. The code may look indirect, but the setter is still happening before React has finished rendering.

  • Setter call directly in the component body.
  • onClick={setX(value)} instead of passing a callback.
  • Inline helper that mutates state while JSX is being built.
  • Parent-child update loops started from render-time code.

How to Fix It Cleanly

Move the update behind a real event handler if the state changes in response to user input. If the value depends on a previous state, use the functional updater form so React gives you the latest value without forcing you to read from a stale closure.

If the value is derived from props or from another piece of state, compute it directly instead of storing a mirrored copy. That often removes the setter entirely.

  • Pass a function reference to event props.
  • Use functional state updates when the next value depends on the previous value.
  • Keep render pure: describe the UI first, mutate state later.
  • Delete duplicated state that can be derived inline.

Broken render-time setter and fixed version

Broken render-time setter and fixed version
function DockCounter() {\n  const [count, setCount] = useState(0);\n\n  // Wrong state changes during render\n  if (count < 3) {\n    setCount(count + 1);\n  }\n\n  return <p>Berth changes: {count}</p>;\n}\n\nfunction DockCounterFixed() {\n  const [count, setCount] = useState(0);\n\n  function advanceCounter() {\n    setCount((current) => current + 1);\n  }\n\n  return (\n    <button type="button" onClick={advanceCounter}>\n      Berth changes: {count}\n    </button>\n  );\n}

Callback prop passed correctly

Callback prop passed correctly
function BadgeResetter() {\n  const [visible, setVisible] = useState(true);\n\n  return (\n    <div>\n      {/* Wrong executes immediately */}\n      <button onClick={setVisible(false)}>Hide badge</button>\n\n      {/* Correct waits for the click */}\n      <button onClick={() => setVisible(false)}>Hide badge</button>\n\n      {visible && <span>Harbor notice</span>}\n    </div>\n  );\n}

How to Debug the Loop

Search for every setter call in the render path, including helpers that the component body calls directly. If the render is nested inside a map callback or ternary, that still counts as render-time work.

Then inspect the event props. A prop that receives the result of a function call will execute immediately; a prop that receives the function itself will wait for the event.

  • Look for setX(...) inside the return path.
  • Check whether onClick, onChange, or similar props are receiving a callback reference.
  • Log the render count if the loop is hidden behind a condition.
  • Inspect parent-child state handoffs if both components are updating each other.

Too Many Rerenders Failure Cases

  • Calling a setter directly in JSX.
  • Passing setCount(value) instead of a callback.
  • Storing a value in state when it can be derived from props or other state.
  • Using the previous value without the functional updater form.

Best Practices

  • Keep the render path free of state mutations.
  • Pass callback references to events.
  • Use functional updaters for state that depends on previous state.
  • Prefer derived values over mirrored state.
  • Treat any render-time setter as a bug, not a convenience.
Before you move on

Too many re renders in React Fix Infinite Loop Mastery Check

5 checks
  • Check for setters in the component body and inside helper functions called from render.
  • Make sure event handlers receive callbacks, not the result of calling those callbacks.
  • Use the functional form when the next value depends on the previous one.
  • Remove state that only mirrors a prop or a calculation you can do inline.
  • If the component keeps re-rendering, log the render count and look for the first setter that repeats.

Try this next

React JS Too Many Rerenders Repair Drills

0 of 2 completed

  1. Reproduce the loop caused by onClick={setCount(count + 1)}, pass a callback instead, and assert one click produces one state transition. JSX should receive the function that handles the event, not the result of calling it during render.
  2. Find state that is being synchronized inside the component body, derive it from props or move the transition to an intentional event, and compare render counts. A render must calculate UI from current state without scheduling another render unconditionally.

React JS Questions Learners Ask

The most common cause is executing a state setter while React is rendering. Examples include setCount(count + 1) directly in the component body or onClick={setCount(count + 1)} in JSX.

Wrap the call in a function so React receives a handler instead of the result of running the setter: onClick={() => setState(value)}. The same rule applies when passing arguments to any event handler.

A useEffect loop is usually reported as "Maximum update depth exceeded," because the update happens after render commits. "Too many re-renders" usually means the setter ran during render itself. The distinction matters because the fix is different.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.