A Deep Dive into React Component Lifecycle

Just like every other lifecycle, React Component Lifecycle is also a loop. It starts with creating it, then mounting it on the DOM and unmounting it when it’s destroyed. This is what React Component Lifecycle actually is!

The beauty of React is that it provides ‘hooks.’ These are the methods that get called automatically at each stage of the lifecycle. A good know-how of these hooks gives the ability to efficiently control and manipulate what goes on in a component throughout its lifetime.

React component lifecycle is often categorized into three parts:

  • Mounting
  • Updating
  • Unmounting

However, React-16 announced a new method that will allow it to stand on its own. So, let’s have a look at these methods and how they can be implemented.

Mounting methods

A component is generally mounted when its first created and implanted into the DOM. It usually takes place when it is rendered for the first time.

The methods that are available during this period are:

  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()

The componentWillMount() Method

The componentWillMount method is called right before a component mounts or the render method is called.

But the truth is that this method is very sparsely used in any React application. So, let’s have a brief look at the reason why it’s being rarely used.

The componentWillMount method fits between the constructor method and the render method which is a very odd position for componentWillMount method.

It can be used as a default configuration for a component as it is implemented before the render method.

There is no need to change the configuration again as there is no significant alteration between these two methods. Also, at this point, nothing can be done with the DOM since it is not mounted, and the render method has not been called.

It’s a common notion for many of us that this is the right place to make API calls for client-side rendering, but this should not be done. This means that the component might render with empty data at least, as the API calls are asynchronous, and the data might not be returned before the render method gets called once.

However, there is one way to make use of this method, i.e. by performing any setup that can be done at runtime, just like connecting external APIs like Firebase.

To avoid making use of this method, this setup should be done at the highest level of component like a root component.

So, let’s have a look at a simple example that can be tried to test if this method actually gets called before the component is rendered:

class Example extends React.Component {

        componentWillMount() {

            console.log(‘I am about to say hello’);

        }

 

        render() {

            return <h1>Hello world</h1>;

        }

    }

The componentDidMount() Method

componentDidMount() method is available only after the component has been mounted. Exactly after the HTML from render has completed the loading process.

It is generally called once in the component life cycle and it is a way to confirm that the component and all its sub-components have rendered properly.

At this point the component is mounted and is readily available to the DOM, this is the exact place to make API calls feasible.

Usually, componentDidMount is a good place to do all the setup you couldn’t have done without the DOM. So here are some of the things that can be done with this method:

  • Connect a React app to external applications, such as web APIs or JavaScript frameworks.
  • Set Timers using setTimeout or setInterval.
  • Add event listeners.
  • Draw on an element that has just been rendered.

In real-time scenario, anything that can be set up in the DOM can be done here.

So, let’s have a look at an example of using the componentDidMount method to make API calls:

class Example extends React.Component {

        componentDidMount() {

            fetch(url).then(results => {

                // Do something with the results

            })

        }

    }

Updating Methods

Generally, after mounting the components don’t always remain in the same state. Many times, the underlying props change due to external reasons and the component has to be re-rendered. The updating lifecycle methods give you control over when and how this updating should take place.

Let’s have a look at the five updating lifecycle methods and they are called in the order they appear below:

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

The componentWillReceiveProps() Method

Props are hooked to the state of the parent component and are externally passed in to a component by its parent component.

So, if in any case, the state of the parent component changes, then the props passed to the component changes and it must be updated. If the props are tied to the state of the component, a change in it will mean a change in the state of the component.

 

componentWillReceiveProps is a method that is called before a component does anything with the new props.

In this method, new props are called as a new argument and have access to the new set of props as well as the present ones. So, this method helps in comparing the present props with the new ones and check if anything has changed during the process.

class Example extends React.Component {

      constructor(props) {

        super(props);

        this.state = {number: this.props.number};

      }

 

      componentWillReceiveProps(nextProps) {

        if (this.props.number !== nextProps.number) {

          this.setState({number: nextProps.number});

        }

      }

 

      render() {

        return (

          <h1>{this.state.number}</h1>

        )

      }

    }

this.state.number in the above example will only be updated if the new number is different from the previous one. So, if there is no difference, then the state is not updated.

The shouldComponentUpdate() Method

If there is a new state of props or the component re-renders after receiving a new set of props, then in that scenario this method is called. It generally receives two arguments, next props, and the next state. The default behavior is for a component to re-render once there’s a change of state of props.

In React, shouldComponentUpdate is used to detect if a component’s output is not affected by a change of props or state in the component and thus should not re-render.

In that scenario, it returns either a true or false value. If it returns a true value, then the component will move forward and will perform how it performs usually and re-render the component. If it returns a false value, then the component will not move forward and will not be updated. But, on a crucial note, this does not prevent child components from re-rendering when their state changes.

The best way to use this method is to have it return false and hence the component will not update under certain conditions. If those conditions are met, then the component does not update.

In the given example, the component will only update if the new input is different from the previous one:

class Example extends React.Component {

      [...]

     shouldComponentUpdate(nextProps, nextState) {

        if (this.state.input == nextState.input) {

          return false;

        }

      }

 

      [...]

    }

The componentWillUpdate() Method

In componentWillUpdate method preparation is performed before the re-rendering occurs. Also, you cannot call this.setState in this method.

One of the unique thing that can be done with this method is that things outside react architecture can be easily contacted. Also, if there is any non-React setup before the rendering of any component occurs such as checking window size or interacting with an API, componentWillUpdate can be used.

In another scenario, if you are using shouldComponentUpdate and need to perform things while changing the prop, then this method can blindly be used.

In this scenario, it is preferable to use it instead of componentWillReceiveProps and it will be called only when the component will actually be re-rendered. However, if you need state to change in response to change in props, use componentWillReceiveProps instead.

Let’s have a look at the syntax:

class Example extends React.Component {

      [...]

 

      componentWillUpdate(nextProps, nextState) {

          // Do something here

      }

 

      [...]

    }

The componentDidUpdate() Method

componentDidUpdate is generally called in that scenario where any rendered HTML has finished loading. Then t receives two arguments, the props and state of the component before the current updating period began.

In non-React environments like in browser or while making HTTP requests, componentDidUpdate proves itself to be the best place to perform.

But, one thing has to be noted that this should be done as long as you compare the current props to the previous props to avoid unnecessary network requests.

So, let’s have a look at an example of it in use:

class Example extends React.Component {

      [...]

    componentDidUpdate(prevProps, prevState) {

        if (this.props.input == prevProps.input) {

          // make ajax calls

          // Perform any other function

        }

      }

 

      [...]

    }

Unmounting method

Unmounting method is an inevitable process in react component lifecycle because components do not always stay in the DOM, there may be times when they have to be removed due to changes in state or some related circumstances.

The unmounting method helps in handling unmounting of components

The componentWillUnmount() Method

componentWillUnmount is the only unmounting method and is called right before when the component is removed from the DOM.

This is the void gap where you can perform any cleanups that should be done on priority. It can be any of the task such as invalidating timers, removing event listeners, canceling network requests or canceling subscriptions made in componentDidMount.

class Example extends React.Component { 

      [...]

 

      componentWillUnmount() {

          document.removeEventListener("click", SomeFunction);

      }

 

      [...]

    }

The componentDidCatch() method

componentDidCatch method is that parameter which detects if a component becomes an error boundary.

In this method, this.setState can be called and used to catch an unhandled JavaScript error in a child component tree and display a fallback UI instead of the component that crashed. These errors are caught during rendering, in lifecycle methods, and in constructors of the whole tree below them.

Let’s see how this method can be used in error boundaries:

class ErrorBoundary extends React.Component {

      constructor(props) {

        super(props);

        this.state = { hasError: false };

      }

 

      componentDidCatch(error, info) {

        this.setState({hasError: true });

      }

 

      render() {

        if (this.state.hasError) {

          return <h1> Oops!!! Broken </h1>;

        }

 

        return this.props.children;

      }

    }

React is an extremely powerful JavaScript framework and is becoming the new realm of understanding how the component lifecycle works.

In the near future it will have the capability to unlock new potential for power that you can explore.



Leave a Reply