This warning appears in React 16.9+ when using the deprecated componentWillReceiveProps lifecycle method. React renamed it to UNSAFE_componentWillReceiveProps to signal its incompatibility with future async rendering, and recommends migrating to getDerivedStateFromProps or componentDidUpdate.
This warning indicates that your React component is using the componentWillReceiveProps lifecycle method, which was deprecated in React 16.3 and produces warnings starting in React 16.9. The method has been renamed to UNSAFE_componentWillReceiveProps to reflect that it can cause issues with React's upcoming concurrent rendering features. The componentWillReceiveProps method has historically been misused for performing side effects (like data fetching) and updating state in ways that can cause bugs. As React moves toward async rendering, these "unsafe" lifecycle methods can be called multiple times before a render actually commits, making them unreliable for operations with side effects. React strongly encourages developers to migrate away from this pattern entirely, using getDerivedStateFromProps for deriving state from props, or componentDidUpdate for side effects that need to run after prop changes.
Check the console warnings to see which components are triggering the warning. The warning message will typically include the component name. You can also search your codebase:
grep -r "componentWillReceiveProps" src/Or use your IDE's search feature to find all occurrences.
React provides an automated codemod script that renames all deprecated lifecycle methods to their UNSAFE_ versions:
npx react-codemod rename-unsafe-lifecyclesThis will scan your project and automatically rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps. This is a quick fix that suppresses the warning in non-strict mode, but is not the recommended long-term solution.
If your componentWillReceiveProps performs side effects like data fetching, API calls, or subscriptions, move them to componentDidUpdate:
// Before
componentWillReceiveProps(nextProps) {
if (nextProps.userId !== this.props.userId) {
this.fetchUserData(nextProps.userId);
}
}
// After
componentDidUpdate(prevProps) {
if (this.props.userId !== prevProps.userId) {
this.fetchUserData(this.props.userId);
}
}Note the logic reversal: componentDidUpdate receives previous props, while componentWillReceiveProps received next props.
If you're using componentWillReceiveProps to derive state from props, migrate to the static getDerivedStateFromProps method:
// Before
componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.props.value) {
this.setState({ controlledValue: nextProps.value });
}
}
// After
static getDerivedStateFromProps(props, state) {
if (props.value !== state.controlledValue) {
return { controlledValue: props.value };
}
return null;
}Important: getDerivedStateFromProps is static, so you cannot access this. Return an object to update state, or null for no updates.
If you were using componentWillReceiveProps to reset component state when props change, consider making the component fully controlled or use a key prop to reset it:
// Parent component
<MyComponent key={userId} userId={userId} />Changing the key forces React to unmount and remount the component with fresh state, eliminating the need for lifecycle-based state synchronization.
If you were computing values from props in componentWillReceiveProps, consider computing them during render with useMemo (if using hooks) or memoization libraries:
// Functional component with hooks
const expensiveValue = useMemo(() => {
return computeExpensiveValue(props.data);
}, [props.data]);For class components, compute during render and cache in instance variables if needed.
If warnings come from third-party libraries, check for updated versions:
npm outdated
npm update react-select react-datesMany popular libraries have released updates that eliminate these warnings. Check the library's changelog or GitHub issues for migration guidance.
After refactoring, verify that your components behave correctly:
npm test
npm run buildPay special attention to:
- Components that derive state from props
- Side effects triggered by prop changes
- Performance-sensitive components
- Edge cases where props change rapidly
The UNSAFE_ prefix doesn't mean the methods are inherently buggy or insecure - it means they are unsafe to use with React's upcoming concurrent rendering mode. In concurrent mode, React may call these methods multiple times before committing a render, or may call them without committing at all. This makes them unreliable for side effects.
If you're using StrictMode in development, React intentionally double-invokes certain lifecycle methods to help catch bugs. This can make the warnings more prominent.
For React 17+, the old lifecycle names (without UNSAFE_) will stop working entirely. The UNSAFE_ variants will continue to work but are not recommended for new code.
When migrating to getDerivedStateFromProps, be aware of a common anti-pattern: blindly copying props to state on every render. React's official blog post "You Probably Don't Need Derived State" explains why this is usually a code smell and offers better alternatives like fully controlled components or components with key-based reset.
For complex state derivation logic, consider whether you actually need to derive state at all. Often, computing values directly during render (potentially memoized) is simpler and less error-prone than maintaining synchronized derived state.
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