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 legacycomponentWillReceiveProps
.
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:
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()
ResourcesClick to expand/shrink