Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

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.

Common Causes

  • useEffect with no dependency array that sets state unconditionally
  • useEffect dependency includes an object/array that's recreated every render
  • setState called inside useEffect that depends on the state being set
  • Parent and child components updating each other's state in a cycle
  • Callback prop recreated on every render causing child useEffect to loop

Quick Fix (TL;DR)

Quick Solution
// ❌ 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

Problem
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}
; }
Solution
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

Problem
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!
}
Solution
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

Problem
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!
}
Solution
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

Problem
const [items, setItems] = useState([]);

// ❌ items in deps + setItems → infinite loop
useEffect(() => {
  setItems([...items, newItem]);
}, [items]);
Solution
// ✅ 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

  • Always add dependency arrays to useEffect - Never omit them
  • Use functional state updates - setState(prev => ...) avoids needing state in deps
  • Use primitive values as dependencies - Avoid objects and arrays
  • Memoize objects with useMemo - Stable references for complex deps
  • Memoize callbacks with useCallback - Stable function references
  • Add conditions before setState in effects - Only update when value actually changes
  • Use eslint-plugin-react-hooks - Warns about missing or incorrect dependencies

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


Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.