Skip to main content

Deprecating unsafe lifecycle methods

· 3 min read
Luke Owen
Lead Front End Developer @ Lunio

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.

note

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]);