As we know react is made up of components and every component goes through a phase that we call component lifecycle. The lifecycle is divided into 4 phases –
- Mounting Phase
- Updating phase
- Unmounting Phase
- Error Handling
Lets understand all the above 4 phases or lifecycle with a code.
1. Mounting
When an instance of a component is being created and inserted into the DOM
import React from "react"; class LearnClass extends React.Component { constructor(props) { super(props); console.log("inside constructor"); //1st } static getDerivedStateFromProps(state) { console.log("inside getDerivedStateFromProps"); //2nd return null; } componentDidMount() { console.log("inside component did mount"); //4th } render() { console.log("inside render"); //3rd return ( <> <h1>{this.props.roll}</h1> </> ); } } export default LearnClass;
In the above code,
- constructor() is always the first method invoked even before the component is mounted on the DOM(that’s why all the initialization is done here).
- static getDerivedStateFromProps(props,state) is a new React lifecycle method as of React 17 designed to replace componentWillReceiveProps . It takes props and state as a parameter. It enables a component to update its internal state(derived state) as the result of changes in props. it is one of the rarely used lifecycles. It comes in handy when you want to change the state value, even before the component is rendered. This fuctuo is called everytime when a state or props value is changd Read More
The below code explains how state value is changed using getDerivedStateFromProps.
Here the value of “age” changes even before the component is mounted on the DOM.
import React from "react"; class LearnClass extends React.Component { constructor(props) { super(props); this.state = { age: 24 }; } static getDerivedStateFromProps(state, props) { return { age: 25 }; //changing state } // incMethod = () => { this.setState({ age: 26}); } render() { return ( <> <h1>{this.state.age}</h1> <button onClick={() => incMethod()}>Click me </button> </> ); } } export default LearnClass;
- render() method is the only required in this phase. Its main function is to display the jsx to the DOM, meaning render the element on the screen. If you don’t want to render anything, you can even return null or boolean. Lastly, render() method is a pure function.
- componentDidMount() is invoked immediately after the component is mounted onto the DOM.
Whenever state or props are changed, 2 functions will always be invoked. getDerivedStateFromProps() and render()
2. Updating
Whenever a change is made to the state or props of a React component, the component is re-rendered. In simple terms, the component is updated.
Below are the method called in a sequential manner when DOM is updated.
- getDerivedStateFromProps() is called everytime when DOM is re-rendered. We have talked about it in the Mounting phase, so we will skip it here. It is rarely used in updating state.
- shouldComponentUpdate(nextProps , nextState) give you control over component re-render. Here you can compare the existing state and prop values with the next props and state values, and return true or false to let react know that component is re-render/update or not. It is mostly used for performance optimization methods. It is also rarely used.
import React from "react"; class Lifecycle extends React.Component { constructor(props) { super(props); console.log("inside constructor"); this.state = { age: 24 }; } static getDerivedStateFromProps(state, props) { console.log("inside getDerivedStateFromProps "); //1 return null; //changing state } incMethod = () => { this.setState({ age: this.state.age + 1 }); }; shouldComponentUpdate = () => { console.log("inside shouldComponentUpdate"); //2 return true; //if this is false or null , component will not render }; componentDidMount = () => { console.log("inside componentDidMount"); }; render() { console.log("inside render"); //3 return ( <> <h1>{this.state.age}</h1> <button onClick={() => this.incMethod()}>Click me</button> </> ); } } export default Lifecycle;
- render() is called immediately after shouldComponentUpdate method, depending on the returned value from shouldComponentUpdate, which defaults to true
- getSnapshotBeforeUpdate(prevProps, prevState) is called right before the changes from the virtual dom are to be reflected in actual DOM. It stores the previous value of state or props, once the DOM is updated. It is rarely used lifecycle method. Important – the value queried from the DOM in
getSnapshotBeforeUpdate
refers to the value just before the DOM is updated, even though therender
method was previously called. This method will either return null or value. The return value will b passed to the next method componentDidUpdate(prevProps, prevState,snapshot)
The getSnapshotBeforeUpdate React lifecycle method doesn’t work on its own. It is meant to be used in conjunction with the componentDidUpdate lifecycle method.
- componentDidUpdate(prevProps, prevState, snapshot) – This method is invoked after the
getSnapshotBeforeUpdate
. This method is guaranteed to be called only once the render is finished in the re-render cycle. We can apply side effects i.e ajax call can be done. It is called once so compare the old props and new props and then decide you want to do ajax call or not.
Understand all the 5 phases with code –
import React from "react"; class Lifecycle extends React.Component { constructor(props) { super(props); this.state = { age: 24 }; } static getDerivedStateFromProps(state, props) { console.log("inside getDerivedStateFromProps "); //1 return null; //changing state } incMethod = () => { this.setState({ age: this.state.age + 1 }); }; shouldComponentUpdate = () => { console.log("inside shouldComponentUpdate"); //2 return true; //if this is false or null , component will not render }; componentDidMount = () => { console.log("inside componentDidMount"); //3 }; getSnapshotBeforeUpdate = () => { console.log("inside getSnapshotBeforeUpdate"); //4 return null; }; componentDidUpdate = () => { console.log("inside componentDidUpdate "); //5 }; render() { console.log("inside render"); //3 return ( <> <h1>{this.state.age}</h1> <button onClick={() => this.incMethod()}>Click me</button> </> ); } } export default Lifecycle;
3. Unmounting
The componentWillUnmount lifecycle method is invoked immediately before a component is unmounted and destroyed.
4. Error handling
The following methods are invoked when an error is thrown by a descendant component (i.e., a component below them).
static getDerivedStateFromError() – Whenever an error is thrown in a descendant component, this method is called first, and the error thrown passes as an argument.
componentDidCatch() – This method is also called after an error in a descendant component is thrown. Apart from the error
thrown, it is passed one more argument which represents more information about the error.
import React, { Component } from "react"; class ErrorBoundary extends Component { state = { hasError: false }; static getDerivedStateFromError(error) { console.log(`Error log from getDerivedStateFromError: ${error}`); return { hasError: true }; } componentDidCatch(error, info) { console.log(`Error log from componentDidCatch: ${error}`); console.log(info); } render() { return null } } export default ErrorBoundary;