If you’ve worked with React for a while, you’ve likely run into this error:
“Too many re-renders. React limits the number of renders to prevent an infinite loop.”
This happens when your component falls into an infinite re-render loop—a common issue in real-world React development.
In this article, we’ll break down the most frequent causes of this error and show you the correct patterns to fix them.
- Pattern 1: Calling setState During Rendering
- Pattern 2: Incorrect useEffect Dependencies
- Pattern 3: Executing Handlers During Render Instead of Passing Them
- Pattern 4: Misconfigured useMemo / useCallback Dependencies
- Pattern 5: Passing New Object/Function Props From the Parent on Every Render
- Summary: Checklist for Debugging “Too many re-renders”
Pattern 1: Calling setState During Rendering
This is the number one cause of infinite re-renders.
❌ Wrong
const MyComponent = () => {
const [count, setCount] = useState(0);
if (count === 0) {
setCount(1); // Updating state during render → infinite loop
}
return <div>{count}</div>;
};
Calling setState (or setCount) while the component is rendering triggers a new render, which calls setState again… and so on.
✅ Correct (useEffect)
useEffect(() => {
if (count === 0) setCount(1);
}, [count]);
Pattern 2: Incorrect useEffect Dependencies
Putting values that change on every render in the dependency array leads to infinite loops.
❌ Wrong
useEffect(() => {
setUser({ name: 'Alice' }); // New object every time
}, [user]);
Because user becomes a new object each time, React thinks the dependency changed on every render.
✅ Correct
useEffect(() => {
setUser((prev) => ({ ...prev, name: 'Alice' }));
}, []);
Pattern 3: Executing Handlers During Render Instead of Passing Them
❌ Wrong
<button onClick={setCount(count + 1)}>Click</button>
This calls the function immediately instead of passing it, causing updates every render.
✅ Correct
<button onClick={() => setCount(count + 1)}>Click</button>
Pattern 4: Misconfigured useMemo / useCallback Dependencies
If you put changing values in the dependency array, React recreates the memoized function or value on each render—possibly triggering state updates inside.
❌ Wrong
const fn = useCallback(() => {
setState(Math.random()); // Causes dependency changes → infinite loop
}, [state]);
✅ Correct
const fn = useCallback(() => {
setState((v) => v + 1);
}, []);
Pattern 5: Passing New Object/Function Props From the Parent on Every Render
Inline objects and functions create new references each render, which can trigger updates in child components.
❌ Wrong (Parent)
<Child config={{ theme: 'dark' }} />
🎯 Fix (Memoize in Parent)
const config = useMemo(() => ({ theme: 'dark' }), []);
<Child config={config} />;
Summary: Checklist for Debugging “Too many re-renders”
When this error appears, verify the following:
- Are you calling state setters (setState/useState) during render?
- Does your
useEffectdependency array contain values that change every render? - Are you accidentally invoking event handlers instead of passing functions?
- Are
useMemoanduseCallbackdependencies configured correctly? - Are you passing inline objects or functions as props?
If you systematically check these points, you’ll resolve most infinite re-render loops quickly.

