← Debugging Guides

阅读中文版本

React Cannot Update a Component While Rendering Another

Fix "Cannot update a component while rendering a different component" by moving state updates out of render, into effects or event handlers.

intermediatedebuggingreactrenderpurity

Symptoms

  • React warns "Cannot update a component (X) while rendering a different component (Y)"
  • A parent re-renders unexpectedly with a stale value
  • The warning appears only in StrictMode

Possible causes

  • A child calls a parent setter during its own render
  • Derived state is computed in render and pushed to another component inline
  • An effect runs during render because it is actually a conditional call, not a hook

Diagnosis steps

Read both component names in the warning

grep -rn "setState\|set[A-Z]" src/components | head

Interpretation

The warning names the renderer and the updated component; the caller of the setter is the culprit.

Move the update to an effect or handler

git diff src/components/Counter.jsx

Interpretation

Relocating the call into useEffect or an onClick resolves the render-phase update.

Root cause

React must not mutate another component's state during the render phase, because renders are supposed to be pure. Calling a setter from another component mid-render violates purity and produces this warning.

Fix

Keep render pure: compute derived values locally, trigger updates from effects or event handlers, and lift state or use a context/reducer when siblings must coordinate.

Risk note

Ignoring the warning can lead to tearing where different components read inconsistent state in the same commit.

Verify the fix

Reproduce in StrictMode and confirm the warning is gone; React DevTools should show consistent props across siblings.

Symptoms

This guide profiles the failure behind “React Cannot Update a Component While Rendering Another”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • React warns “Cannot update a component (X) while rendering a different component (Y)”
  • A parent re-renders unexpectedly with a stale value
  • The warning appears only in StrictMode

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Read both component names in the warning

grep -rn "setState\|set[A-Z]" src/components | head

The warning names the renderer and the updated component; the caller of the setter is the culprit.

Step 2: Move the update to an effect or handler

git diff src/components/Counter.jsx

Relocating the call into useEffect or an onClick resolves the render-phase update.

Likely contributors, in order of frequency:

  • A child calls a parent setter during its own render
  • Derived state is computed in render and pushed to another component inline
  • An effect runs during render because it is actually a conditional call, not a hook

Root Cause

React must not mutate another component’s state during the render phase, because renders are supposed to be pure. Calling a setter from another component mid-render violates purity and produces this warning.

The Fix

Keep render pure: compute derived values locally, trigger updates from effects or event handlers, and lift state or use a context/reducer when siblings must coordinate.

Watch out: Ignoring the warning can lead to tearing where different components read inconsistent state in the same commit.

// ❌ updating another component during render
// function List({ items, onCount }) {
//   onCount(items.length); // called during render
//   return items.map((i) => <li key={i}>{i}</li>);
// }

// ✅ report via effect
function List({ items, onCount }) {
  useEffect(() => { onCount(items.length); }, [items.length, onCount]);
  return <ul>{items.map((i) => <li key={i}>{i}</li>)}</ul>;
}

Verify and Prevent

Reproduce in StrictMode and confirm the warning is gone; React DevTools should show consistent props across siblings.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.