How to Fix "Too Many Re-renders" Error in React
I ran into this simple React error, which was telling me that I had too many re-renders and that I was approaching an infinite render loop.
Invariant Violation: Too many re-renders. React limits
the number of renders to prevent an infinite loop
This is a simple example of what could trigger this error.
const Component = () => {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={setOpen(!open)}>Toggle!</button>
<span>{open.toString()}</span>
</>
);
};
It seems as though we are calling our state setter (setOpen
in this case) immediately after render. These state setters will re-invoke the render process, which will then call our state setter again, which will force a re-render again, and so on.
Solution and Explanation
The issue with our code is that our state setter is being invoked immediately upon render, which means something isn’t acting as expected.
In this scenario, the onClick={setOpen(!open)}
fires upon render instead of onClick
, creating this infinite loop.
In order to fix this, we can “add an event” to our event handler by changing the onClick
handler to be onClick={(event) => setOpen(!open)}
.
We won’t include the event
parameter since it’ll be unused.
const Component = () => {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(!open)}>Toggle!</button>
<span>{open.toString()}</span>
</>
);
};
Extracting the Handler
Another solution could be to extract the handler out into a function.
const Component = () => {
const [open, setOpen] = useState(false);
const handler = () => {
setOpen(!open);
};
return (
<>
<button onClick={handler}>Toggle!</button>
<span>{open.toString()}</span>
</>
);
};