Tutorials Logic, IN info@tutorialslogic.com

Cannot update component while rendering React Fix

What is "Cannot update a component while rendering a different component"?

This warning appears when rendering is no longer pure. A component should calculate JSX during render, not trigger updates to itself, its parent, or another component while that calculation is happening.

The fix is usually to move the update into an event handler for user actions or into useEffect for updates that must happen after React commits the render.

This React warning occurs when a component triggers a state update in another component during the render phase. React's rendering must be a pure, side-effect-free process. Calling setState or a state updater function during rendering "" even indirectly through a child component "" violates this rule and can cause infinite render loops or inconsistent UI states.

Common Causes

  • Calling a parent's setState directly inside a child component's render body
  • Invoking a state setter function during the render phase instead of in an event handler
  • Missing or incorrect dependency array in useEffect causing state updates during render
  • Passing an immediately-invoked function as an event handler instead of a function reference
  • Calling state updates inside render logic conditionals

Quick Fix (TL;DR)

Immediate Fix: Problem setState called during render

Immediate Fix: Problem setState called during render
// Wrong Problem "" setState called during render
function Child({ onUpdate }) {
  onUpdate("new value"); // Called during render!
  return <div>Child</div>;
}

// Correct Solution "" move to useEffect
function Child({ onUpdate }) {
  useEffect(() => {
    onUpdate("new value"); // Called after render
  }, [onUpdate]);
  return <div>Child</div>;
}

Common Scenarios & Solutions

Calling a state setter directly in the component body (outside of event handlers or effects) triggers a state update during the render phase, causing React to warn and potentially loop.

When a child component calls a parent's state setter (passed as a prop) directly in its render body, it updates the parent's state while the parent is still rendering, causing this warning.

A useEffect without a dependency array runs after every render. If it updates state, it triggers another render, which runs the effect again "" creating an infinite loop that also triggers this warning.

Passing onClick={setState(value)} instead of onClick={() => setState(value)} immediately calls the function during render instead of waiting for the click event.

Failure: Called during render causes warning

Failure: Called during render causes warning
function App() {
  const [count, setCount] = useState(0);

  // Wrong Called during render "" causes warning
  setCount(count + 1);

  return <div>{count}</div>;
}

Correction: State updates in event handlers

Correction: State updates in event handlers
function App() {
  const [count, setCount] = useState(0);

  // Correct State updates in event handlers
  const handleClick = () => setCount(c => c + 1);

  return <button onClick={handleClick}>{count}</button>;
}

Failure: Called during render

Failure: Called during render
function Parent() {
  const [title, setTitle] = useState("");
  return <Child setTitle={setTitle} />;
}

function Child({ setTitle }) {
  setTitle("Hello from Child"); // Wrong Called during render!
  return <div>Child</div>;
}

Correction: Use useEffect to update parent after render

Correction: Use useEffect to update parent after render
function Child({ setTitle }) {
  // Correct Use useEffect to update parent after render
  useEffect(() => {
    setTitle("Hello from Child");
  }, []); // Empty deps "" runs once after mount

  return <div>Child</div>;
}

Failure: No dependency array runs after every render

Failure: No dependency array runs after every render
function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then(result => setData(result));
    // Wrong No dependency array "" runs after every render!
  });

  return <div>{data}</div>;
}

Correction: Empty array runs only once after mount

Correction: Empty array runs only once after mount
function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then(result => setData(result));
  }, []); // Correct Empty array "" runs only once after mount

  return <div>{data}</div>;
}

Failure: SetActive(true) is called immediately during render

Failure: SetActive(true) is called immediately during render
function App() {
  const [active, setActive] = useState(false);

  return (
    // Wrong setActive(true) is called immediately during render!
    <button onClick={setActive(true)}>Activate</button>
  );
}

Correction: Arrow function wraps the call only runs on click

Correction: Arrow function wraps the call only runs on click
function App() {
  const [active, setActive] = useState(false);

  return (
    // Correct Arrow function wraps the call "" only runs on click
    <button onClick={() => setActive(true)}>Activate</button>
  );
}

Best Practices

  • Keep render pure - The render function (component body) should only compute and return JSX. No side effects, no state updates.
  • Use useEffect for side effects - Any state update triggered by mounting, data fetching, or subscriptions belongs in useEffect.
  • Always add dependency arrays to useEffect - An empty [] runs once; list specific deps to run when they change.
  • Use function references in event handlers - Pass onClick={handleClick} not onClick={handleClick()}.
  • Use React DevTools - The Profiler tab shows which components are re-rendering and why, helping diagnose update loops.
  • Lift state up carefully - When sharing state between components, lift it to the nearest common ancestor and pass setters as props "" but only call them in effects or handlers.
  • Enable React Strict Mode - Strict Mode double-invokes renders in development to help surface these issues early.

Why Render Must Stay Pure

React may call render more than once, especially in development Strict Mode. If rendering also changes state, the same render calculation can trigger another render, which can trigger another update, making the UI unpredictable.

A pure render reads props and state and returns JSX. Side effects such as setState, navigation, subscriptions, storage writes, and analytics should happen after render or in response to events.

  • Do not call setState directly in the component body.
  • Do not update parent state while a child is rendering.
  • Use event handlers for click, submit, and change updates.
  • Use useEffect for synchronization after render.

Parent and Child Update Pattern

This warning often appears when a child component checks a prop and immediately calls a parent setter during render. The child render is still in progress, but the parent update asks React to start another render path.

Move that parent update into useEffect with a precise dependency array. If the update is caused by a user action, move it into the event handler instead.

  • Mount-time synchronization belongs in useEffect.
  • User-triggered updates belong in event handlers.
  • Derived values should often be calculated instead of stored.
  • Avoid setting state only to mirror props unless there is a real need.

Wrong: Updating Parent During Child Render

Wrong: Updating Parent During Child Render
function Child({ count, setStatus }) {
  if (count > 10) {
    setStatus("limit reached"); // Wrong during render
  }

  return <p>{count}</p>;
}

Correct: Move Update to useEffect

Correct: Move Update to useEffect
function Child({ count, setStatus }) {
  useEffect(() => {
    if (count > 10) {
      setStatus("limit reached");
    }
  }, [count, setStatus]);

  return <p>{count}</p>;
}
Before you move on

Cannot update component while rendering React Fix Mastery Check

5 checks
  • Search the component body for setState or parent setter calls.
  • Move user-triggered updates into event handlers.
  • Move render-driven synchronization into useEffect.
  • Check child components that call parent callbacks immediately.
  • Remove unnecessary mirrored state when a derived value is enough.

React JS Questions Learners Ask

React expects render to calculate JSX from the current props and state without causing new updates. If a child calls a parent setter while the child is rendering, React is forced to change another component before the current render has finished.

The child is usually where the forbidden call happens, even though the state being changed belongs to the parent. A common pattern is passing setSelected or setCount into a child, then calling it directly during the child render instead of inside a handler.

Pass a callback prop from the parent, but call it only at a safe time.

Browse Free Tutorials

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