Each Class Component has several “lifecycle methods” that you can override to run code at particular times in the process.
A React component can go through four stages of its life as follows.
React provides the developers a set of predefined functions that if present is invoked around specific events in the lifetime of the component. Developers are supposed to override the functions with desired logic to execute accordingly.
These methods are called in the following order when an instance of a component is being created and inserted into the DOM:
The constructor
for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props
will be undefined in the constructor, which can lead to bugs.
constructor(props) {
super(props);
// Don't call this.setState() here!
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
getDerivedStateFromProps()
is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.
This method exists for rare use cases where the state depends on changes in props over time. For example, it might be handy for implementing a Transition component that compares its previous and next children to decide which of them to animate in and out.
static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps");
if (nextProps.color !== prevState.color) {
return { color: nextProps.color };
}
return null;
}
It requires static
to be used in start and we can't recall this
.
The render()
method is the only required method in a class component.
render()
The render()
function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.
componentDidMount()
is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
When we call this method, the component we made already appeared on the screen. What we usually do in this stage is connecting to an external library which uses DOM like D3 and masonry or requesting ajax through axios and fetch to get needed data or reading and changing the attributes of DOM directly.
An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered:
We already mentioned about it in Mounting.
If there is a change in props
or state
, then this method is called.
Use shouldComponentUpdate()
to let React know if a component’s output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.
shouldComponentUpdate()
is invoked before rendering when new props or state are being received. Defaults to true. This method is not called for the initial render or when forceUpdate()
is used.
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate", nextProps, nextState);
// if the last number is 4, then no rerendering
return nextState.number % 10 !== 4;
}
we already mentioned!
getSnapshotBeforeUpdate()
is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle method will be passed as a parameter to componentDidUpdate()
.
This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll position in a special way.
A snapshot value (or null) should be returned.
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
if (prevProps.color !== this.props.color) {
return this.myRef.style.color;
}
return null;
}
componentDidUpdate()
is invoked immediately after updating occurs. This method is not called for the initial render.
Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate", prevProps, prevState);
if (snapshot) {
console.log("color right before updating: ", snapshot);
}
}
getSnapshotBeforeUpdate()
is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle method will be passed as a parameter to componentDidUpdate()
.
This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll position in a special way.
A snapshot value (or null
) should be returned.
getSnapshotBeforeUpdate(prevProps, prevState) {
// It's right before DOM updating
// to keep scrolling even new data is added on top
// scrollHeight is to set the scroll's position
// scrollTop is to stop this function
// if it already exists
if (prevState.array !== this.state.array) {
const { scrollTop, scrollHeight } = this.list;
// returning value will be given by componentDidMount as snapshot
return {
scrollTop,
scrollHeight
};
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot) {
const { scrollTop } = this.list;
if (scrollTop !== snapshot.scrollTop) return; // it this function already exists, then no need to work
const diff = this.list.scrollHeight - snapshot.scrollHeight;
this.list.scrollTop += diff;
}
}
This method is called when a component is being removed from the DOM:
componentWillUnmount()
is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount()
.
You should not call setState() in componentWillUnmount()
because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again.
componentWillUnmount() {
console.log("componentWillUnmount");
}
These methods are called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component.
Sources
Official React Document:
https://reactjs.org/docs/react-component.html
Others:
https://www.geeksforgeeks.org/reactjs-lifecycle-components/
https://react.vlpt.us/basic/25-lifecycle.html