Madushan PereraMadushan Perera

Published on February 24, 2021

React Component Life Cycle

Understanding React lifecycle methods with class components

React Component Life Cycle

What is React Life Cycle?

React life cycle is a set of stages which are related to React components, since the React component is created (initialize) and mounted to the DOM until it’s removing from the DOM is called as a React Life Cycle. It's like a life cycle of a biological life. But's this is all about a React Component 😊

Different stages of React Life Cycle and related methods.

Basically, React Life cycle can be divided into 3 main stages according to how the component renders to the DOM respectively mounting, Updating and Unmounting from the DOM.

Before and after rendering those React components to the DOM we can manipulate our components as we want by firing React life cycle methods. In this case React has provide those React life cycle methods to do our necessary change into our components such as updating the state of our components.

Main Component lifecycle methods.

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount
react-component-life-cycle-diagram

Let’s have an idea of what’s happening in the React life cycle and methods with the above diagram.

Constructor

In the stage of mounting, we have a function named constructor. As you can see this function executes on the initial stage of a component. When comes to React we have stateless and stateful components. So, to initialize the state of a class component, we need this constructor. If we don’t have any initial state or any bind methods, we can omit this function.

js

import React, { Component } from "react";
class TestClassComponent extends Component {
constructor(props) {
super(props);
this.state = { message: "initialize state" };
this.logData = this.logData.bind(this);
}
logData(data) {
console.log(data);
}
render() {
return <h1>Hello I am a class Component</h1>;
}
}
export default TestClassComponent;

Since our class component extends from the parent of React.Component we need to have the super(props) function inside of the constructor and this should be placed at the top before any props.

render()

This is the only required method in React class component. After the initiation of props this render method executes. In this method we can define our HTML elements as jsx elements and those elements get render into the DOM via ReacDOM.render method to the “root” of the DOM. Normally we can see this “root” element in every React application and that will be the entry point of our application.

js

import React, { Component } from "react";
class TestClassComponent extends Component {
render() {
return <h1>Hello I'm a class Component</h1>;
}
}
export default TestClassComponent;

componentDidMount()

This method is invoked when the component is mounted to the DOM. Let’s assume that we need to fetch data some API end point or subscribe into an event listener. So, componentDidMount() in the place you want to instantiate those logics.

js

import React, { Component } from "react";
class TestClassComponent extends Component {
constructor(props) {
super(props);
this.state = { message: "initialize state" };
this.logData = this.logData.bind(this);
}
logData(data) {
console.log(data);
}
componentDidMount() {
logData(data);
}
render() {
return <h1>Hello I am a class Component</h1>;
}
}
export default TestClassComponent;

Now our component is mounted to the DOM. But what will happen if we needed to update the state of our component?

Think about a counter app that use can press a button to increase a number count. When use press the button the count should be increase. So, the count state should be update in every single button click.

js

import React, { Component } from "react";
class CountMe extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.incrementCount = this.incrementCount.bind(this);
this.decrementCount = this.decrementCount.bind(this);
}
incrementCount = () => this.setState({ count: this.state.count + 1 });
decrementCount = () => this.setState({ count: this.state.count - 1 });
componentDidMount() {
console.log("componentDidMount");
//put your data fetching code here
//we can use this to add event listeners.
}
componentDidUpdate(prevProps) {
console.log("componentDidUpdate");
//After updating the state we can check the diff of those two state.
if (this.props.count !== prevProps.count) {
console.log("State is updated");
}
}
componentWillUnmount() {
console.log("componentDidUpdate");
//we can use this to remove event listners.
}
render() {
return (
<>
<h1>Hello I am a class Component</h1>
<h1>Count : {this.state}</h1>
<button onClick={this.incrementCount}>+ Increment</button>
<button onClick={this.decrementCount}>- Decrement</button>
</>
);
}
}
export default CountMe;

Now we invoke with a function to update our counter using setState function. Every time we call this setState function, the render() method is called and tries to update the DOM with our component including the new state.

componentDidUpdate()

When the component is update with new state and rendered into the DOM, this componentDidUpdate() method is called. But this method is not called for the initial render of the component. This method takes three arguments respectively prevProps, prevState, snapshot. We can use them to check whether our state is changed or not. Based on that we can write our logic on it. Otherwise, it may cause an infinite loop. So, it better to wrap the setState function with a condition of the diff between previous and current props.

componentWillUnmount()

This is a function which executes before the component removes from the DOM. We can say when the component is about to remove from the DOM this function gets executed.

Most commonly we use this function to remove event subscribers from the application when the component is removed from the DOM.

Conclusion

React Life Cycle is very useful when comes to dynamic applications. From a component initiation to the destruction (removing from the DOM) we can take the full control of this component by using React Life Cycle methods. Mainly componentDidMount, componentDidUpdate, componentWillUnmount are the methods which are using in the React Life Cycle.

When comes to React function component we can’t use these class methods in a React function component. Therefore, React has introduced React hooks to maintain the React Life Cycle in a functional component. Let’s talk about this point in a coming post.

Happy Coding! 🎉