"Too many re-renders" is a React runtime error that fires when a component updates itself infinitely, crashing the browser tab.
It means your component’s render cycle never settles — it keeps scheduling new renders until React gives up.
This is a browser-side error, not a Node.js or TypeScript issue, so you’ll see it in the console as Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
What "Too many re-renders" Means
React has a safety cap (default 50 renders per update cycle) to prevent infinite loops from freezing the page.
When a component triggers a state update during its own render — or inside a useEffect that runs on every render — React detects the loop and throws this error.
It’s not a performance warning; it’s a hard stop that unmounts your component tree.
Why It Happens
The most common real causes, in order of frequency:
- Calling a state setter directly in the render body — e.g.,
setCount(count + 1)at the top level of your component. Each render calls the setter, which schedules another render, forever. - A
useEffectwith no dependency array that calls a setter — the effect runs after every render, updates state, causing a re-render, which runs the effect again. This is a loop with a one-render delay, so it’s harder to spot. - Passing an inline function to a child component that immediately invokes it — e.g.,
<Child onClick={() => setState(...)} />whereChildcallsonClick()during its own render. The parent re-renders, passes a new function, child re-renders, calls it again.
Example Code That Triggers It
Here’s the minimal, runnable React component that throws this exact error in the browser console:
import { useState } from "react";
export default function BrokenCounter() {
const [count, setCount] = useState(0);
// ❌ Direct setter call in render body — infinite loop
setCount(count + 1);
return <p>Count: {count}</p>;
}
Run this in any React app (Create React App, Vite, Next.js) and you’ll get Error: Too many re-renders within milliseconds. The render function executes setCount, which schedules a new render, which calls setCount again — React hits the 50-render cap and throws.
How to Fix It
The corrected version moves the state update into an event handler or a useEffect with proper dependencies:
import { useState, useEffect } from "react";
export default function FixedCounter() {
const [count, setCount] = useState(0);
// ✅ Correct: update state in response to an event
const handleIncrement = () => setCount(count + 1);
// ✅ Or, if you need it on mount, use an effect with an empty dependency array
useEffect(() => {
setCount(1); // runs once, not on every render
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={handleIncrement}>Increment</button>
</div>
);
}
The fix works because state updates are now triggered by discrete events (a click or a component mount) rather than the render cycle itself. The useEffect with [] runs only after the first render, so it doesn’t re-trigger itself. If you need to update state based on a prop change, pass that prop in the dependency array — but never call a setter directly in the render body.
Common Mistakes That Cause This
Mistake 1: Updating state in a derived value calculation.
You write const doubled = setCount(count * 2) thinking it’s a computed value. It’s not — it’s a state update that runs every render. Use useMemo or plain arithmetic instead: const doubled = count * 2.
Mistake 2: Forgetting the dependency array in useEffect.
You write useEffect(() => { setData(fetchData()); }) with no []. The effect runs after every render, fetches data, sets state, and re-renders — looping forever. Always add [] if the effect should run once, or list the specific dependencies that should trigger it.
When Should You Worry About This?
You should worry when the error appears in production, not just during development — it means a user’s browser tab is crashing. The error itself is a symptom, not the root cause, so the real question is: is your state update logic tied to the render cycle? If yes, fix it immediately. If it only happens in dev with React StrictMode (which double-invokes renders), it’s likely a false positive — but verify your effects have correct dependencies anyway, because StrictMode is just exposing a latent bug. You should also worry if you’re using a state management library like Redux or Zustand and the error persists after fixing local state — check for a selector that returns a new object reference on every call, which triggers infinite re-renders in connected components.
Next time you see Too many re-renders, check the component’s render body first — look for any setState call that isn’t inside an event handler or an effect with a dependency array. That’s the culprit 90% of the time.