This React error occurs when a component attempts to update another component's state during the render phase. React prevents this to maintain a predictable rendering flow and avoid infinite loops or race conditions.
This warning is React's way of telling you that you are trying to modify the state or props of a component while it is in the process of rendering another component. React is designed to prevent such scenarios to maintain a predictable rendering flow and to avoid potential issues like infinite loops. State updates should be scheduled in response to events or in lifecycle methods, not during the rendering of a component. When you call setState() or trigger a state change during render, it can cause the parent component to re-render, which then triggers the child component to render again, potentially creating an infinite loop. This violation of React's component lifecycle rules typically happens when developers inadvertently call state-setting functions in the component body (outside of useEffect or event handlers), or when props passed to a child component trigger state updates in the parent during the child's render phase. React's strict mode and development builds catch these issues early to prevent unpredictable behavior in production.
Open React DevTools in your browser and check the console warning stack trace. The warning message will indicate which component (Component X) is trying to update another component (Component Y) during render.
Look for the component names in the warning message:
Warning: Cannot update a component (Parent) while rendering
a different component (Child).Use the stack trace to locate the exact file and line number where the state update is occurring.
If you're calling setState directly in your component body, wrap it in a useEffect hook:
Before (causes warning):
function ChildComponent({ data, onUpdate }) {
if (data.needsUpdate) {
onUpdate(data); // ❌ Updates parent during render
}
return <div>{data.value}</div>;
}After (correct):
function ChildComponent({ data, onUpdate }) {
useEffect(() => {
if (data.needsUpdate) {
onUpdate(data); // ✅ Updates after render completes
}
}, [data, onUpdate]);
return <div>{data.value}</div>;
}The useEffect hook ensures the state update happens after rendering is complete.
Move state-setting logic from the component body to event handlers:
Before:
function Parent() {
const [count, setCount] = useState(0);
function Child({ value }) {
setCount(value); // ❌ Called during Child's render
return <div>{value}</div>;
}
return <Child value={5} />;
}After:
function Parent() {
const [count, setCount] = useState(0);
function Child({ value, onClick }) {
return (
<button onClick={() => onClick(value)}>
{value}
</button>
);
}
return <Child value={5} onClick={setCount} />;
}This ensures state updates only happen in response to user interactions, not during render.
If you're using useMemo to trigger state updates, switch to useEffect:
Before:
function Component({ data }) {
const [processed, setProcessed] = useState(null);
useMemo(() => {
setProcessed(transform(data)); // ❌ useMemo is for memoization, not side effects
}, [data]);
return <div>{processed}</div>;
}After:
function Component({ data }) {
const [processed, setProcessed] = useState(null);
useEffect(() => {
setProcessed(transform(data)); // ✅ useEffect is for side effects
}, [data]);
return <div>{processed}</div>;
}Remember: useMemo is for computed values, useEffect is for side effects including state updates.
If your child component is receiving callback props that update parent state, wrap them in useCallback:
function Parent() {
const [value, setValue] = useState('');
// ✅ Memoized callback prevents child re-renders
const handleChange = useCallback((newValue) => {
setValue(newValue);
}, []);
return <Child onChange={handleChange} />;
}
function Child({ onChange }) {
useEffect(() => {
onChange('updated value');
}, [onChange]);
return <div>Child</div>;
}This prevents the callback reference from changing on every render, reducing unnecessary re-renders.
If refactoring is complex, you can temporarily wrap state updates in setTimeout to defer them:
function Component({ onUpdate }) {
useEffect(() => {
setTimeout(() => {
onUpdate(newValue); // Deferred to next tick
}, 0);
}, [onUpdate]);
return <div>Content</div>;
}Note: This is a workaround, not a proper fix. It's better to restructure your component logic to follow React's lifecycle patterns. Use this only for quick debugging or legacy code that needs immediate patching.
If using Redux, ensure useSelector isn't triggering state updates during render:
function Component({ dispatch }) {
const userData = useSelector(state => state.user);
// ❌ Don't dispatch during render
// if (!userData.loaded) {
// dispatch(loadUser());
// }
// ✅ Dispatch in useEffect
useEffect(() => {
if (!userData.loaded) {
dispatch(loadUser());
}
}, [userData.loaded, dispatch]);
return <div>{userData.name}</div>;
}State management libraries can trigger cascading updates if not used carefully within React's lifecycle.
Why React enforces this rule: React's reconciliation algorithm expects rendering to be a pure function of props and state. When components update other components during render, it breaks this assumption and can lead to unpredictable behavior, infinite loops, or performance issues.
Class components: In class-based components, this same pattern applies. Never call setState() in the render() method. Use componentDidMount(), componentDidUpdate(), or event handlers instead.
React Strict Mode: In development, React.StrictMode may cause this warning to appear more frequently because it intentionally double-invokes certain lifecycle methods to help identify issues. This is expected behavior and helps catch bugs early.
Performance impact: While the warning itself doesn't break your app, the underlying issue can cause severe performance problems. Each improper state update during render can trigger additional renders, creating a cascade that impacts user experience.
Testing considerations: When writing tests with React Testing Library or Enzyme, be aware that this warning may appear in test output if your components have this issue. Use act() wrapper for state updates in tests to avoid false positives.
Prevention in CI/CD: Configure your build pipeline to treat React warnings as errors by setting REACT_APP_ESLINT_FAIL_ON_WARNING=true or using ESLint rules like react-hooks/rules-of-hooks and react-hooks/exhaustive-deps to catch these issues during development.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React