The Problem

React enforces a strict rule: state updates must happen during event handlers or effects, never during the render phase itself. When you break this rule, React throws a hard error in development mode.

Symptoms

  • Red error screen: "Cannot update a component while rendering a different component"
  • The error names both the calling component and the target component
  • App works in some flows but crashes on specific user interactions
  • Error only appears in React 18+ with Strict Mode enabled

The Root Cause

This error occurs when one component triggers a state update in another component (or itself) during the render phase. Common triggers include:

  1. 1.Calling setState directly in the component body (not inside an effect or handler)
  2. 2.A parent passing a callback that mutates child state, and the child calls it during render
  3. 3.Context consumers updating context values during render

Real Error Message

bash
Error: Cannot update a component (`App`) while rendering a different
component (`Child`). To locate the bad setState() call inside `Child`,
follow the stack trace as described in the React docs.
    at Child
    at div
    at App

Real-World Scenario

```javascript // BAD: State update during render function Child({ onValueChange }) { const [value, setValue] = useState('');

// This runs during render! It calls parent's setState during child's render. onValueChange(value);

return <input value={value} onChange={e => setValue(e.target.value)} />; }

function App() { const [childValue, setChildValue] = useState(''); return <Child onValueChange={setChildValue} />; } ```

How to Fix It

Fix 1: Move the Update to useEffect

```javascript function Child({ onValueChange }) { const [value, setValue] = useState('');

useEffect(() => { onValueChange(value); }, [value, onValueChange]);

return <input value={value} onChange={e => setValue(e.target.value)} />; } ```

Now the parent state update happens inside an effect, after render completes.

Fix 2: Use a Ref for Deferred Updates

```javascript function Child({ onValueChange }) { const [value, setValue] = useState(''); const pendingRef = useRef(value);

useEffect(() => { if (pendingRef.current !== value) { onValueChange(value); pendingRef.current = value; } }, [value, onValueChange]);

return <input value={value} onChange={e => setValue(e.target.value)} />; } ```

Fix 3: Lift State Up Properly

javascript
// Better architecture: parent owns the state
function App() {
  const [value, setValue] = useState('');
  return <input value={value} onChange={e => setValue(e.target.value)} />;
}

If the parent needs the value, it should own the state directly rather than having the child push it up during render.

Prevention

  • Never call setState in the component body outside of event handlers
  • Use the react-hooks/exhaustive-deps ESLint rule
  • Enable React Strict Mode in development to catch these errors early
  • Keep state ownership clear: the component that needs the value should own it