What Triggers This ErrorOpen your browser console and you'll see this staring back at you:
Warning: Cannot update a component from inside the function body of a different component.
React detected that during component A's render phase, something triggered a state update in component B. Renders must be pure โ no side effects, no state mutations. Cross-component updates are forbidden here. Three patterns account for most occurrences:
- A child calls a parent's state setter (passed as a prop) directly inside its render body- A Redux or Context action dispatched during render- A custom hook that fires a callback synchronously during render, not inside
useEffect## Reproduce the BugThis minimal example reliably triggers the warning:
// Parent.jsx
function Parent() {
const [status, setStatus] = useState('idle');
return (
<div>
<p>Status: {status}</p>
<Child onReady={() => setStatus('ready')} />
</div>
);
}
// Child.jsx โ BROKEN
function Child({ onReady }) {
onReady(); // <-- called during render, updates Parent state
return <div>Child content</div>
}
When Child renders, it calls onReady() immediately. That call hits setStatus inside Parent. React catches this and throws the warning.
Quick Fix: Move the Call Into useEffectWrap the call in useEffect โ it runs after render, not during:
// Child.jsx โ FIXED
import { useEffect } from 'react';
function Child({ onReady }) {
useEffect(() => {
onReady();
}, []); // runs once after first render
return <div>Child content</div>
}
The side effect is out of the render phase now. onReady fires after mount โ exactly where it belongs.
Watch the dependency array. If onReady is recreated on every parent render, this effect runs in a loop. Stabilize it with useCallback in the parent:
// Parent.jsx
const handleReady = useCallback(() => {
setStatus('ready');
}, []);
<Child onReady={handleReady} />
Fix for Redux / Context Dispatch During RenderDispatching inside the component body is the same mistake, different syntax:
// BROKEN
function NotificationBadge({ hasNew }) {
if (hasNew) {
dispatch(markAsSeen()); // <-- during render!
}
return <span>{hasNew ? 'New' : ''}</span>
}
// FIXED
function NotificationBadge({ hasNew }) {
useEffect(() => {
if (hasNew) {
dispatch(markAsSeen());
}
}, [hasNew, dispatch]);
return <span>{hasNew ? 'New' : ''}</span>
}
Fix for Callbacks That Notify a Parent During RenderA subtler version: the child calls a prop callback conditionally during render to notify the parent of some internal condition. Looks harmless. It's not:
// BROKEN โ callback updates parent state during Dropdown's render
function Dropdown({ isOpen, onStateChange }) {
if (isOpen) {
onStateChange('open'); // triggers state update in a different component
}
return <div>...</div>
}
// FIXED
function Dropdown({ isOpen, onStateChange }) {
useEffect(() => {
onStateChange(isOpen ? 'open' : 'closed');
}, [isOpen, onStateChange]);
return <div>...</div>
}
Worth knowing: updating a component's own state during render is a different story. React explicitly allows it, provided you use a guard condition:
// OK โ updating own state with a guard (hooks replacement for getDerivedStateFromProps)
function Dropdown({ isOpen }) {
const [open, setOpen] = useState(false);
if (isOpen !== open) {
setOpen(isOpen); // React re-renders immediately, skips the intermediate commit
}
return <div>...</div>
}
React re-renders the component immediately without committing the intermediate state. Only updating another component's state is banned during render.
Fix for Custom Hooks That Fire Callbacks During RenderCustom hooks can hide the same problem. When a hook calls a callback inside the hook body rather than inside useEffect, you get the same warning โ just harder to spot:
// Broken custom hook
function useDataLoader(onLoad) {
const data = fetchFromCache();
if (data) {
onLoad(data); // fires during render!
}
return data;
}
// Fixed custom hook
function useDataLoader(onLoad) {
const data = fetchFromCache();
useEffect(() => {
if (data) {
onLoad(data);
}
}, [data, onLoad]);
return data;
}

