Deprecating unsafe lifecycle methods
Back in React 16.3.0 (March 2018) some lifecycle methods were deprecated, these were:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
In last months 16.9.0 update these names now throw console warnings. In React version 17, they’re going to stop working. This might not happen for a while but if you’re still using them: its time to think about updating.
Short term: UNSAFE_ prefix
For the time being these methods will continue to work with an UNSAFE_
prefix.
- UNSAFE_componentWillMount
- UNSAFE_componentWillReceiveProps
- UNSAFE_componentWillUpdate
To save you going through your code and renaming each method, React has provided a npx script:
npx react-codemod rename-unsafe-lifecycles
This will rename all the old methods, methods with this new prefix should continue to work throughout React 17.
Long term: replacing them
componentWillMount
This is called just before the component mounts. There’s no long term replacement for this: it won’t be supported in the future.
If you used it to initialize state:
In class-based components, you can use the constructor
constructor(props) {
super(props);
this.state = {
loading: true,
}
}
For functional components, you can use the useState hook
// Top of the file
import React, { useState } from 'react';
// Inside the component
const [loading, setLoading] = useState(true);
If you’re used it for side-effects (e.g. AJAX)
Then you should use componentDidMount
instead, this is called as soon as the component is mounted.
For classes
componentDidMount() {
const { slug } = this.props;
getPostBySlug(slug)
.then((data) => {
// do something with it
});
}
For functions
The useEffect
hook can handle this, I have a post on this if you want to see how it works.
// Top of the file
import React, { useEffect } from 'react';
// Inside the component
useEffect(() => {
const { slug } = props;
getPostBySlug(slug)
.then((data) => {
// do something with it
});
}, []);
componentWillReceiveProps & componentWillMount
This is called just before a component receives new props. For most cases we can replace it with componentDidUpdate
– called just after a component is updated.
If this doesn’t work for you then you can also use getDerivedStateFromProps
But you almost certainly don’t need it
For classes
componentDidUpdate(prevProps, prevState) {
if(prevState.thing !== this.state.thing) {
// do something
}
}
For functions
We can again use the useEffect
hook, but this time we’re not passing a second parameter. This means it’ll be called after every render.
// Top of the file
import React, { useEffect } from 'react';
// Inside the component
useEffect(() => {
// do something
});
If you don’t want it to run on every render, you can pass an array of values as a second parameter.
It will only run if any of those values change.
useEffect(() => {
// do something if 'thing' is changed
}, [thing]);