DEV Community

Balraj Jha Anand
Balraj Jha Anand

Posted on

React lifecycle methods

What is React lifecycle

A component goes through many different stages from the moment it is created till it is removed. Since our UI is dynamic, to respond to those ever-changing conditions React has given has methods so that we are able to track those changes and therefore respond to them appropriately. In this post, I will cover 4 of them: render, componentDidMount, componentDidUpdate and shouldComponentUpdate


render

The job of render is to return whatever markup you have written inside of it. Whenever the state of a component changes it will cause the render method to be called again thus the user is able to see the updated content. We use setState to change the state of a component which makes React update the component to reflect the changes and thus call the render method again.

simple example of render

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      counter: 0,
    }
  }

  handleButtonClick = (event) => {
    this.setState({
      counter: this.state.counter + 1,
    });
  }

  render() {
    return (
      <>
        <h1>{`Counter: ${this.state.counter}`}</h1>
        <button onClick={this.handleButtonClick}>Click me</button>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The above code will display a button that changes the state of the counter, and after every click render will be called again because React detected the change in state. So, we will see the updated counter value whenever we click the button thanks to the render function being called again.

Few things to note about render function is that:

  • A class component must have a render method, think of this as kind of a contract you make with React you must follow whenever you create a class that extends React.Component.
  • You must not call setState directly inside the render function as React will detect a change which will cause a re-render which will detect setState and cause re-render again and so on and on which makes your app go in an infinite loop and crash.

componentDidMount

The componentDidMount method is called just once when the component is inserted into the DOM. It is typically used to make API requests and set the initial state or initiailze state which requires DOM nodes.

example of componentDidMount

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      productsOnSale: []
    }
  }

  getDailyDealsData() {
    // API request to get data about what products are on sale
    this.setState({
      productsOnSale: data, // data from API about what products are on sale
    });
  }

  componentDidMount() {
    this.getDailyDealsData();
  }

  render() {
    return (
      <>
        <h1>Daily Deals</h1>
        <p>{this.state.productsOnSale}</p>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Think of the case when you go to the homepage of an e-commerce site like Amazon and you see the daily deals section first. You as a user didn't interact with the website yet but you still see a deals section when the page got loaded. The above code tries to simulate that.

So above example first initializes an empty productsOnSale array through the constructor and when the component is inserted into DOM it makes an API request through getDailyDealsData function which will update the state of productsOnSale and render that data to the browser.

We only need to fetch information about daily deals once at the start when you first load the page and this is a practical example where componentDidMount can be used.


componentDidUpdate

The componentDidUpdate method gets called whenever the component gets updated, but it is not called for the initial render unlike componentDidMount however, it may run more than once. Let's take an example and try to understand it.

example of componentDidUpdate

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      counter: 0,
    }
  }

  handleButtonClick = (event) => {
    this.setState({
      counter: this.state.counter + 1,
    });
  }
  // ----new function------
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("Component updated");
  }

  render() {
    return (
      <>
        <h1>{`Counter: ${this.state.counter}`}</h1>
        <button onClick={this.handleButtonClick}>Click me</button>
        {console.log("render")}
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The above example is similar to the one in render example but here we have defined an extra method componentDidUpdate which gets called whenever the component updates. We are changing the value of counter whenever the button is clicked hence this is causing the componentDidUpate to run and log in to the console "Component updated".

Also, note that when you load the app for the first time and check the console, there is no "Component updated", it will only run after the initial render.

You might have noticed that componentDidUpdate also has some parameters, I will explain their usage below.

another componentDidUpdate example

componentDidUpdate(prevProps, prevState, snapshot) {
    if (prevState.searchTerm !== this.state.searchTerm) {
      // make API request
      this.searchVideos(this.state.searchTerm);
    }
  }
Enter fullscreen mode Exit fullscreen mode

Suppose you are using youtube to search for videos. You searched for "React tutorials" and got the results, then you cleared the input and searched for "React tutorial" again, youtube can opt to not make the same search request again as that would be a waste and thus there will be no update to the component. We can do this like in the example above, we are comparing prevState with the current state and if there are different search terms, then only make the API request.


shouldComponentUpdate

The shouldComponentUpdate dictates whether the component will get updated or not. We can return true if we want the component to update otherwise we return false. For e.g. I will add a new function to our render example.

example of shouldComponentUpdate

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      counter: 0,
    }
  }

  handleButtonClick = (event) => {
    this.setState({
      counter: this.state.counter + 1,
    });
  }
  // ------new function----
  shouldComponentUpdate(nextProps, nextState) {
    if (nextState.counter % 2 !== 0) {
      console.log("Not updated");
      return false;
    } else {
      return true;
    }
  }
  render() {
    return (
      <>
        <h1>{`Counter: ${this.state.counter}`}</h1>
        <button onClick={this.handleButtonClick}>Click me</button>
      </>
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

We just add shouldComponentUpdate function and now our functionality of the counter will change as it will now display only "even" values. This happens because we are stopping the re-render from happening if the counter is odd. Internally state is indeed getting updated and if we click on the button again we will see the value of 2, 4, 6, and so on. We will not see any "odd" numbers even though setState method is run, hence render is not called again to show the updated state.


Hope you now understand what is lifecycle in react and their methods. If you find any mistakes here kindly let me know in the comments

Top comments (0)