Maximum update depth exceeded in React - Fix (2026) | Tutorials Logic
What is This Error?
The "Maximum update depth exceeded" error occurs when React detects a component is stuck in an infinite update loop. This typically happens when useEffect or componentDidUpdate triggers a state update that causes a re-render, which triggers the effect again — endlessly.
Error Message:
Error: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
Common Causes
Quick Fix (TL;DR)
// ❌ Problem — no dependency array, infinite loop
useEffect(() => {
setCount(count + 1); // Sets state → re-render → effect runs again
});
// ✅ Solution 1 — empty array, runs once
useEffect(() => {
setCount(1);
}, []);
// ✅ Solution 2 — functional update, no dependency needed
useEffect(() => {
setCount(prev => prev + 1);
}, []); // Only runs on mount
Common Scenarios & Solutions
Scenario 1: useEffect Without Dependency Array
function Timer() {
const [time, setTime] = useState(0);
// ❌ No dependency array — runs after every render
useEffect(() => {
setTime(time + 1); // Sets state → re-render → effect runs → infinite!
});
return {time};
}
function Timer() {
const [time, setTime] = useState(0);
// ✅ Use setInterval with cleanup
useEffect(() => {
const interval = setInterval(() => {
setTime(prev => prev + 1); // Functional update — no dependency needed
}, 1000);
return () => clearInterval(interval); // Cleanup
}, []); // Empty array — runs once on mount
return {time};
}
Scenario 2: Object in Dependency Array
function Search({ query }) {
const [results, setResults] = useState([]);
const filters = { query, page: 1 }; // ❌ New object every render!
useEffect(() => {
fetchResults(filters).then(setResults);
}, [filters]); // filters changes every render → infinite loop!
}
function Search({ query }) {
const [results, setResults] = useState([]);
// ✅ Use primitive values as dependencies
useEffect(() => {
fetchResults({ query, page: 1 }).then(setResults);
}, [query]); // Only re-run when query string changes
}
// ✅ Or memoize the object
const filters = useMemo(() => ({ query, page: 1 }), [query]);
Scenario 3: Callback Prop Causing Child Loop
function Parent() {
const [data, setData] = useState(null);
// ❌ New function reference every render
const onLoad = (result) => setData(result);
return ;
}
function Child({ onLoad }) {
useEffect(() => {
fetchData().then(onLoad);
}, [onLoad]); // onLoad changes every render → infinite loop!
}
function Parent() {
const [data, setData] = useState(null);
// ✅ Stable reference with useCallback
const onLoad = useCallback((result) => setData(result), []);
return ;
}
Scenario 4: State Update Depending on Itself
const [items, setItems] = useState([]);
// ❌ items in deps + setItems → infinite loop
useEffect(() => {
setItems([...items, newItem]);
}, [items]);
// ✅ Use functional update — no need to list items as dependency
useEffect(() => {
setItems(prev => [...prev, newItem]);
}, [newItem]); // Only depends on newItem
Best Practices to Avoid This Error
Related Errors
Key Takeaways
- "Maximum update depth exceeded" means useEffect is triggering an infinite state update loop
- Always add a dependency array to useEffect — omitting it runs the effect after every render
- Objects and arrays in dependency arrays cause infinite loops — use primitive values instead
- Use functional state updates (prev => ...) to avoid listing state as a dependency
- Memoize callbacks with useCallback and objects with useMemo for stable references
- Add conditions inside useEffect before calling setState to prevent unnecessary updates
Frequently Asked Questions
Level Up Your React js Skills
Master React js with these hand-picked resources
10,000+ learners
Free forever
Updated 2026
Related React Topics