Understand Life Cycle Methods in React.js
To build a project using React, the first step is to figure out the various Components that are required to bring your project to life! Once you are able to visualize the client-side of your project as a collection of Components, half the battle is won. So it is fair to say that Components form the crux of any React application.
But how does a collection of Components end up becoming a single page application? This is no different to the way every single website is rendered by your browser i.e, by creating a DOM. But in case of React, the Components are first woven into a Virtual DOM and only the necessary modifications are made to the real DOM. In order to do this, React must constantly keep track of every Component built for the project, and this is where we come across the life cycle of a Component.
The following article provides a more elaborate explanation of how a browser renders a web page after creating the DOM. You can check it out if you need some more clarification!
A Component undergoes 3 phases in its life cycle. Think of it as milestones along the course of a Component’s life.
- Mounting: This is the stage where the Component is inserted into the DOM. This phase is accounted for using the componentDidMount() method.
- Updating: This is the stage in which the Component’s state and props can change, leading to the process of re-rendering the Component with the updated state/props.
- Unmounting: This is the final stage of the Component’s life, in which it is removed from the DOM.
Note that sometimes there is another stage which is considered even before a Component is mounted. This is called the Initialization stage, where the Component’s initial state is set. Hence, it is common to see images that depict 4 stages in a Component’s life cycle.
Now let us dive a little deeper into the life cycle methods which can be applied to a Component at various phases. Note that I am deliberately excluding certain deprecated methods.
Before we start learning about the different methods available, it’s better to understand the role that they play.
It is very straight forward too! These methods are like checkpoints along the way. They are invoked only at the very specific phases of a Component’s life cycle. This way, we have more control over a Component’s behavior, which in turn gives us a more flexible approach to building the UI using those Components!
Take a look at the image below, which shows the various methods and the points at which they are invoked.
Let us go over some of the most commonly used life cycle methods, along with examples.
- constructor(): This is used only if you have a class-based Component and it serves the purpose of initializing the state of a Component. In case of functional Components, the useState() hook is used to do the same.
Consider an example in which you are creating a Component to store Todo tasks.
- ComponentDidMount(): As seen from the image in the previous section, this is invoked after a Component is inserted into the DOM for the first time. This has a variety of uses, one of which can be to update state after a Component is mounted, like the example shown below.
- render(): This is the method that is responsible for inserting a Component into the DOM. This is invoked every time a Component’s state/props is updated.
Now let us take a look at the life cycle methods which are invoked during the updating phase of a Component.
- shouldComponentUpdate(): This is invoked immediately after a Component’s state or props is updated. Although most changes are dealt with using the componentDidUpdate() method, this is often a more immediate way of dealing with the change. To take a look at a possible scenario where this comes in handy, you can go through the following article.
- componentDidUpdate(): This is the method invoked after re-rendering an updated Component. This method can give you the information about a Component’s previous state and previous props. A fair warning to give before you start using this method is to never directly set the state of a Component within it. Doing that will change the Component’s state, futher triggering a componentDidUpdate() and so on.
This article provides some safe use cases for this life cycle method. - getSnapshotBeforeUpdate(): This is used only when the developer requires more data about the DOM before the Component was updated and re-rendered. Although this is seldom used, the following article does a very good job of providing an explanation for an important use case.
- getDerivedStateFromProps(): Again, this is a method that is seldom used. I have never come across a scenario which required the use of this specific method, and the team at React seems to agree!
Finally, the only method to deal with the unmounting of a Component.
- componentWillUnmount(): This is invoked just before a Component is removed from the DOM. This is where you can perform any cleanups that need to be done such as invalidating timers, canceling network requests, removing event listeners, and so on.
These are the methods that you are most likely to come across. But as I mentioned earlier, I have omitted certain methods that are deprecated or are set to be deprecated in the very near future. So, in case you run into a legacy system which uses some of the deprecated life cycle methods, you may need to do a bit of Googling!
Lastly, in case you are working with a functional Component, and are having trouble with implementing some of the methods discussed, you can go through the following article.