Too many re-renders
A component changes its own state while it renders, so React renders it again and again until it stops the loop.
Also appears as
- Minified React error #301; visit https://react.dev/errors/301 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Prompt to fix it
My React app crashes with "Too many re-renders. React limits the number of renders to prevent an infinite loop." Find the component that sets state while it renders. Look for event props that call a setter directly, such as onClick={setOpen(true)}, and setter calls in the component body or in custom hooks. Pass event handlers as functions, and replace state that only copies props with values computed during render. Don’t hide the loop with a render counter or try/catch. Tell me which line caused it.
Paste into Layerwise or any AI coding tool.
What it means
React renders a component by calling its function. If that function sets state while it runs, React has to render it again, which sets state again. After 25 rounds React stops and throws this error, and the screen usually goes blank.
The classic cause is an event prop that calls a function instead of passing it. onClick={setOpen(true)} runs setOpen during render. onClick={() => setOpen(true)} hands React a function to call later, when someone clicks.
The error names the component but not the line. Search that component for any call that starts with set and sits outside an event handler or effect, including one inside an if that copies a prop into state.
Common causes
- An event prop calls the state setter directly, as in
onClick={setCount(count + 1)}, so it runs on every render. - The component body calls a setter to copy a prop or a computed value into state, such as
if (items) setCount(items.length). - A custom hook sets state during render, so every component that uses it loops.
How to fix it
- Open the component named in the stack trace and find every call that starts with
set. - Wrap setters in event props in an arrow function:
onClick={() => setOpen(true)}. - Delete state that only copies props or other state, and compute the value during render instead:
const count = items.length. - If state must change after something happens, set it in the event handler that caused it.
Example fix
import { useState } from 'react';
export function Menu({ items }: { items: string[] }) {
const [open, setOpen] = useState(false);
// Computed during render. Storing it in state with a setter here would loop.
const count = items.length;
return (
// Pass a function. onClick={setOpen(!open)} would run during render.
<button onClick={() => setOpen(!open)}>
Menu ({count})
</button>
);
}Related errors
All errorsMaximum update depth exceeded
State updates kept triggering more state updates in a loop, usually through an effect or a callback, so React stopped them.
Rendered more hooks than during the previous render
A component called a different number of hooks than on its last render, usually because a hook sits after an early return or inside an if.
Maximum call stack size exceeded
A function kept calling itself, directly or through other functions, until JavaScript ran out of room to keep track of the calls.
Hydration failed
The HTML the server sent didn’t match what React rendered first in the browser, so React threw that part away and rebuilt it on the client.
Build with an agent that checks its work
The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.