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 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.
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.
function DockCounter() {\n const [count, setCount] = useState(0);\n\n // ❌ 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}
function BadgeResetter() {\n const [visible, setVisible] = useState(true);\n\n return (\n <div>\n {/* ❌ executes immediately */}\n <button onClick={setVisible(false)}>Hide badge</button>\n\n {/* ✅ waits for the click */}\n <button onClick={() => setVisible(false)}>Hide badge</button>\n\n {visible && <span>Harbor notice</span>}\n </div>\n );\n}
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.
Running setState during render.
Move the update into an event handler or another post-render path.
Using onClick={setValue(value)}.
Use onClick={() => setValue(value)} or pass a named handler.
Mirroring props in state without a real need.
Read the prop directly or derive the value inline.
This error occurs when React detects an infinite rendering loop, usually caused by calling setState during the render phase, incorrect event handler syntax, or useEffect without a proper dependency array.
Wrap it in an arrow function: onClick={() => setState(value)}. Without the arrow function, setState is called immediately during render instead of when the button is clicked.
If useEffect has no dependency array, it runs after every render. If it sets state, that triggers another render, creating an infinite loop. Add [] for mount-only or list specific dependencies.
Use React DevTools Profiler to see which component re-renders. Add console.log in the render body to count renders. Check for setState calls outside event handlers and useEffect dependency arrays.
Yes! Objects and arrays are compared by reference in JavaScript. A new object {} !== {} even with the same content, so React sees it as changed every render. Use primitive values or useMemo to stabilize references.
Explore 500+ free tutorials across 20+ languages and frameworks.