This React warning occurs when a component attempts to update the state of another component during the render phase, violating React's lifecycle rules. The solution typically involves moving state updates into useEffect hooks or proper event handlers.
This warning indicates that component A is triggering a state update in component B while component B is still in the middle of its render phase. React's rendering process must complete atomically without side effects - any state updates should be scheduled for after the current render completes, not during it. When you call a setState function (or dispatch action) directly in a component's render body, React cannot guarantee the consistency of the component tree. This violates the rules of hooks and can lead to unpredictable behavior, infinite render loops, or stale state. React added this warning in version 16.13 to help developers catch these problematic patterns early. The error message typically shows which component is attempting the update and which component is currently rendering, making it easier to track down the problematic code path.
Examine the warning message in the console to identify which component is updating state and which is rendering. The warning format is: "Cannot update a component (TargetComponent) while rendering a different component (CurrentComponent)". Look for setState calls, state setter functions, or dispatch calls in CurrentComponent's render body.
// WRONG - setState called directly in render
function ChildComponent({ setParentState }) {
if (someCondition) {
setParentState(newValue); // This causes the warning
}
return <div>Child</div>;
}Wrap the state update logic in a useEffect hook to ensure it runs after rendering completes. Include proper dependencies so the effect only runs when needed.
// CORRECT - setState in useEffect
import { useEffect } from 'react';
function ChildComponent({ setParentState }) {
useEffect(() => {
if (someCondition) {
setParentState(newValue);
}
}, [someCondition, setParentState]);
return <div>Child</div>;
}This tells React to execute the state update after the current render cycle completes.
Ensure event handlers are passed as function references, not invoked immediately. Remove parentheses when passing to event props.
// WRONG - function called immediately
<button onClick={handleClick()}>Click</button>
// CORRECT - function reference passed
<button onClick={handleClick}>Click</button>
// CORRECT - inline arrow function if you need to pass arguments
<button onClick={() => handleClick(id)}>Click</button>If you have conditional logic that updates state, move it outside the render phase or into useEffect.
// WRONG - updating state during conditional render
function MyComponent({ user, setError }) {
if (!user) {
setError('No user found'); // Causes warning
return <div>Loading...</div>;
}
return <div>{user.name}</div>;
}
// CORRECT - use useEffect for side effects
function MyComponent({ user, setError }) {
useEffect(() => {
if (!user) {
setError('No user found');
}
}, [user, setError]);
if (!user) return <div>Loading...</div>;
return <div>{user.name}</div>;
}If using Redux with useSelector, ensure dispatch calls are not happening during render. Move them to useEffect or event handlers.
// WRONG - dispatch during render
function Component() {
const data = useSelector(state => state.data);
if (!data) {
dispatch(fetchData()); // Causes warning
}
return <div>{data}</div>;
}
// CORRECT - dispatch in useEffect
function Component() {
const data = useSelector(state => state.data);
const dispatch = useDispatch();
useEffect(() => {
if (!data) {
dispatch(fetchData());
}
}, [data, dispatch]);
return <div>{data}</div>;
}Navigation functions should be called in response to events or in useEffect, never during render.
// WRONG - navigate during render
function AuthCheck({ isLoggedIn, navigate }) {
if (!isLoggedIn) {
navigate('/login'); // Causes warning
}
return <div>Content</div>;
}
// CORRECT - navigate in useEffect
function AuthCheck({ isLoggedIn, navigate }) {
useEffect(() => {
if (!isLoggedIn) {
navigate('/login');
}
}, [isLoggedIn, navigate]);
return <div>Content</div>;
}After making changes, reload the application and verify the warning no longer appears in the console. Test the functionality to ensure state updates still work as expected. Use React DevTools Profiler to confirm there are no excessive re-renders.
# Clear browser cache and reload
# Check console for warnings
# Test user interactions that trigger state changesThis warning was introduced in React 16.13 as part of stricter development mode checks. It does not appear in production builds but indicates a real problem that could cause bugs.
React 18 Considerations: With React 18's concurrent rendering features, this pattern becomes even more problematic as renders may be interrupted and restarted. Ensure all side effects are properly isolated in useEffect.
State Lifting vs Props: Sometimes this warning indicates a design issue where state is not lifted to the appropriate level. Consider whether the state should live in a parent component or context provider instead of being updated across component boundaries.
Memoization: If you're passing callbacks that update state, wrap them in useCallback to prevent unnecessary re-renders that might trigger this warning:
const handleUpdate = useCallback((value) => {
setState(value);
}, []);Form Libraries: Libraries like react-hook-form may trigger this warning during field registration. Ensure you're following their documentation for proper integration patterns, often involving Controller components or useEffect for programmatic updates.
Testing: This warning can appear in tests when using @testing-library/react. Wrap state-changing actions in act() or waitFor() to properly handle async state updates.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite