How to fix "Cannot update a component while rendering a different component"

React logs a warning in the console:

Warning: Cannot update a component (`Parent`) while rendering a different
component (`Child`). To locate the bad setState() call inside `Child`,
follow the stack trace as described in https://reactjs.org/link/setstate-in-render

The UI sometimes gets into an inconsistent state. What is causing this and how do I fix it?

Solution

This warning means that during the render phase of Child, it is calling a state setter that belongs to an ancestor component. React does not allow side effects during rendering.

The most common pattern that causes this is passing a state setter as a prop and calling it inline in the child's render:

// Broken: calling setCount during render of Child
function Child({ onLoad }: { onLoad: () => void }) {
  onLoad() // called directly in the render body
  return <div>Child</div>
}

function Parent() {
  const [count, setCount] = useState(0)
  return <Child onLoad={() => setCount((c) => c + 1)} />
}

Move the call to a useEffect inside the child so it runs after rendering, not during it:

function Child({ onLoad }: { onLoad: () => void }) {
  useEffect(() => {
    onLoad()
  }, [onLoad])

  return <div>Child</div>
}
Alternative #1

If the state update should happen in response to an event rather than on mount, move the setter call to the event handler instead of the render body:

// Broken: setter called during render
function FilterInput({ onFilterChange }: { onFilterChange: (v: string) => void }) {
  onFilterChange(someComputedValue) // runs during render
  return <input />
}

// Fixed: setter called on user interaction
function FilterInput({ onFilterChange }: { onFilterChange: (v: string) => void }) {
  return (
    <input
      onChange={(e) => onFilterChange(e.target.value)}
    />
  )
}
Alternative #2

Sometimes the root cause is deriving state from props by calling a setter during render as a way to "sync" them. This pattern is unnecessary in React. Compute the derived value directly during render instead:

// Broken: syncing state with props via render-time setter
function ItemList({ items }: { items: string[] }) {
  const [filtered, setFiltered] = useState(items)
  setFiltered(items.filter((i) => i.length > 3)) // called during render!
  return <ul>{filtered.map((i) => <li key={i}>{i}</li>)}</ul>
}

// Fixed: compute derived value directly
function ItemList({ items }: { items: string[] }) {
  const filtered = items.filter((i) => i.length > 3) // no state needed
  return <ul>{filtered.map((i) => <li key={i}>{i}</li>)}</ul>
}

If the computation is expensive, wrap it with useMemo rather than storing the result in state.

Last modified: April 16, 2026
Stay in the loop
Subscribe to our newsletter to get the latest articles delivered to your inbox