React component lifecycle with Hook§
Tags: react, reacthooks, advanced, tutorial
Published: 2019-05-25 01:39:34

---
title: React component lifecycle with Hook§
published: true
description: Let's learn how to have lifecycle methods of react in functional component using hooks in this article. Read on to find it out...
tags: react, reacthooks, advanced, tutorial
canonical_url: https://www.elanandkumar.com/blog/react-comp-lifecycle-with-hooks/
cover_image: https://www.elanandkumar.com//static/21e11959b8a49f2874ccfddad7f8c790/775d9/react-lifecycle.jpg
---
In previous post, I have explained how to convert a class component into functional component so that we can leverage the hooks.
Here is the link to article:

{% link https://dev.to/elanandkumar/react-hooks-migrate-class-component-to-hooks-3879 %}

In this post, I will help you to understand how to get the same output that we used to achieve using component lifecycles with react hooks.

I'll be covering following lifecycle methods:
- `componentWillMount`
- `componentDidMount`
- `componentDidUpdate`
- `shouldComponentUpdate`
- `componentWillUnmount`

Before we start, let's get some understanding about following hooks:
- `useState`
- `useEffect`
### useState
`useState` returns a stateful value and a function to update it.
#### Syntax:
![useState syntax](https://www.elanandkumar.com/static/f6e859f954689b36c47b8bdd9cbdc1e6/5cad1/useState-syntax.jpg)
### useEffect
With functional component, we are not **allowed** to have side effects like mutations, timers, mutations or any other side effects inside the main body of the component.

So, here we have `useEffect` which runs **after** the render happens. By default, effects run after every render but there are ways to control it which we will look into it later in the article.
#### Syntax:
![useEffect syntax](https://www.elanandkumar.com/static/a0e61e77cdc8d734938c1f31ba58d450/9ab67/useEffect-syntax.jpg)

For more details on hooks or for any other hooks provided by react, look at the official documentation.

So, let's start with the component lifecycle and try to understand the replacement of the same with hooks.

> **Pro Tip:** Do not use hooks inside any code blocks. It must be at the top level hierarchy of the functional component.

Let's see the running example of a small application. This usage react class based component and lifecycle. At the end of the article, you can check the same application created using functional component and has the similar lifecycle execution.
{% codepen https://codepen.io/anand-kr/pen/yWzqZd default-tab=js,result %}
Let's begin.
### componentWillMount
When we convert any class component to functional component, we can write the code after defining our states (if any) using `useState` or before the code reaches the render (jsx) part to achieve the `componentWillMount` behaviour. As we know the code execution happens from top to bottom.

### componentDidMount
As explained before about `useEffect`, we can pass the second optionalParameter to achieve the `componentDidMount` behavior. Let's have a look at the following code snippet.
```javascript
React.useEffect(()=>{
  console.log('Robot: componentDidMount');
  // ...code goes here...
  fetchData();
}, []);
```
In the above code, we have blank array `[]` as the second argument at **line 5**. Why? 🤔

Well, because the second argument when provided helps react to invoke the effect only if it detects a change in any of the entries provided. This array is dependencies for the function that we pass as first argument in `useEffect`.

In this case, it is blank which means it is never going to detect any change and so it will invoke only once. Isn't that what `componentDidMount` does? Invokes only once, right?

> Please note that if the second argument is not passed in `useEffect`, it will execute always after render.

### componentDidUpdate
Let's say, we need to invoke api call again if any props changes for the component, we do it in here once the component updates. We can achieve it using `useEffect`. Though, this time, we need to pass an entry to the second argument.
```javascript
React.useEffect(() => {
  console.log('Robot: componentWillUpdate');
  // code goes here
  fetchData();
}, [props.selectedRobotId]);
```
This time, we have passed a prop `selectedRobotId` in the array. So, whenever this prop is going to change, the effect will run and we get the updated component.
### shouldComponentUpdate
This one is a bit tricky but let me help you to understand this. As we all know, this lifecycle method helps us to control the rendering of the component by our self. Following is an example:
```javascript
shouldComponentUpdate(nextProps, nextState) {
  console.log("Robot: shouldComponentUpdate");
  return (
    nextProps.selectedRobotId !== this.props.selectedRobotId ||
    nextState.loadedRobot.id !== this.state.loadedRobot.id ||
    nextState.isLoading !== this.state.isLoading
  );
}
```
But, with functional component, we can not use react component lifecycle methods this way. So, how to achieve this same result?

Well, with react, we have something called `React.memo`. We can wrap out component with this as shown below:
```javascript
export default React.memo(Robot);
```
Does this look right as an alternate to `shouldComponentUpdate`. No.....

Ok, so here is the thing. `React.memo` accepts a second argument (a function) which provides the access to `nextProps` and `prevProps`. This can help us to achieve the same thing as `shouldComponentUpdate`.
```javascript
export default React.memo(Robot, (prevProps, nextProps) => {
  console.log('Robot: shouldComponentUpdate');
  return nextProps.selectedRobotId === prevProps.selectedRobotId;
});
```
> There is one thing to note here. This works opposite of `shouldComponentUpdate`. You return **true** if you do not want to re-render. You return **false** if you want it to render.

React handles this beautifully and so the second function is only needed if you do not want a re-render for any props change. Else, let React handle it for you. :)
### componentWillUnmount
Remember, in the explanation of `useEffect`, I mentioned about an optional return function inside the `useEffect`. This return function serves the purpose of cleanup.
```javascript
React.useEffect(() => {
  console.log('Robot: componentDidUpdate');
  //...code goes here
  fetchData();
  return () => {
    console.log('cleaning up...');
  }
}, [props.selectedRobotId])
```
The above code snippet is similar to `componentDidUpdate` code block except it has a return function now. So, whenever `props.selectedRobotId` changes, this effect runs and the return function invokes on completion of effect where we can do cleanup.
But, this is not what happens with `componentWillUnmount`. Right?
Ok, so to achieve the `componentWillUnmount` we can add one more `useEffect` in our code and pass the second argument as a blank array (`[]`). Similar to the `componentDidMount` but the `useEffect` will have a return function this time inside, which will work as `componentWillUnmount`.
```javascript
React.useEffect(() => {
  //...code goes here
  fetchData();
  return () => {
    console.log('cleaning up...');
  }
}, [props.selectedRobotId]);

React.useEffect(() => {
  //...code goes here
  fetchData();
  return () => {
    console.log('Robot: componentWillUnmount');
  }
}, []);
```
That gives us the way to do clean up at two level. One, when component updates and one when it is ready to unmount.
## Summary
In this article, we covered `useState` and `useEffect`. Then we used `useEffect` and `memo` to achieve the component life cycle methods that we have with class based component.

At first, this might look confusing but do not worry. Here is the codepen for same application (shown above) but using React hooks.

{% codepen https://codepen.io/anand-kr/pen/KLXGJQ default-tab=js,result %}

Please checkout the code and practice. Also, feel free to share it or reach out to me for any questions/concerns.

Happy learning!