A release of React 16.3 gave us new lifecycle methods which are recommended to use in your code. Some of the methods were deprecated, because of their insecurity. But also a few methods were added. So let's go step by step to learn more about these changes.

Legacy methods

Some of our legacy component lifecycles tend to encourage unsafe coding practices. These lifecycle methods have often been misunderstood and subtly misused. Furthermore, their potential misuse may be more problematic with async rendering. They still work, but it is not recommended using them in the new code.

  • componentWillMount

It is invoked just before mounting occurs. Avoid introducing any side-effects or subscriptions in this method.

  • componentWillReceiveProps

Using this lifecycle method often leads to bugs and inconsistencies, and for that reason it is going to be deprecated in the future.

If you need to perform a side effect in response to a change in props, use componentDidUpdate lifecycle instead. In very rare cases, you might want to use the getDerivedStateFromProps lifecycle as a last resort.

  • componentWillUpdate

It is invoked just before rendering when new props or state are being received. Typically, this method can be replaced by componentDidUpdate().

Note: Deprecation warnings will be enabled with a future 16.x release, but the legacy lifecycles will continue to work until version 17. Even in version 17, it will still be possible to use them, but they will be aliased with an UNSAFE_ prefix to indicate that they might cause issues.


New methods

In addition to deprecating unsafe lifecycles, it was also added two new lifecycle methods:

  • getDerivedStateFromProps is being added as a safer alternative to the legacy componentWillReceiveProps.

Here is a comparisson how code could looks like with componentWillReceiveProps and getDerivedStateFromProps:

import React from 'react';

// Using componentWillReceiveProps
class ExampleComponent extends React.Component {
    state = {
        isScrollingDown: false,
    };

    componentWillReceiveProps(nextProps) {
        if (this.props.currentRow !== nextProps.currentRow) {
            this.setState({
                isScrollingDown: nextProps.currentRow > this.props.currentRow,
            });
        }
    }

    // Rest part of the component
}

// Using getDerivedStateFromProps
class ExampleComponent extends React.Component {
    state = {
        isScrollingDown: false,
        lastRow: null,
    };

    static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.currentRow !== prevState.lastRow) {
            return {
                isScrollingDown: nextProps.currentRow > prevState.lastRow,
                lastRow: nextProps.currentRow,
            };
        }

        // If no changes made
        return null;
    }

    // Rest part of the component
}

Pay attention, that your state should always have default values, so new changes came to the getDerivedStateFromProps method could be compared with them.

  • getSnapshotBeforeUpdate is being added to support safely reading properties from e.g. the DOM before updates are made.

This lifecycle isn’t often needed, but can be useful in cases like manually preserving scroll position during rerenders.

Even though the function is not static, it is recommended to return the value, not update the component. The returned value will be passed to componentDidUpdate as the 3rd parameter.


The new life-cycle tree right now looks like this:

React 16.3 lifecycle diagram

Note that if you’re a React application developer, you don’t have to do anything about the legacy methods yet. The primary purpose of the upcoming version 16.3 release is to enable open source project maintainers to update their libraries in advance of any deprecation warnings. Those warnings will not be enabled until a future 16.x release.


TL;DR: Conclusion

Each component has several “lifecycle methods” that you can override to run code at particular times in the process.

Mounting

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

Updating

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

Unmounting

  • componentWillUnmount()