Akhila Ariyachandra

Mimic React life cycle methods with Hooks

Posted on 13th October 2019

8 min read


Until somewhat recently, if you wanted to use state in React you had to use a class component extending from either React.Component or React.PureComponent. The release of React 16.8 brought hooks which allowed state to be used in functional components.

If you wanted to do something like converting an existing class component to a functional component or fetch data in a functional component, you might be wondering how we can bring over the functionality of the life cycle methods. Three of the more popular methods, namely componentDidMount, componentWillUnmount and componentDidUpdate, can all be implemented with a single hook, useEffect.


Say we have a component like this.


The example above is relatively straightforward. We fetch a list of posts once the component loads, the state with response and list them out.

If we write the same thing as a functional component.


Basically all we’re doing is taking the code that was inside componentDidMount and running it inside an effect.

The thing to remember with useEffect if that they run after each render. The second argument in useEffect is used to control when to run the effect. The argument is an array of states which to run the effect after one of them is updated. To make sure the effect only runs once, an empty array is passed as the argument.

If you don't set the 2nd argument in a useEffect where the state is updated, an infinite loop will occur.

While the above effect will run as is, React will show a warning saying that “An effect function must not return anything besides a function, which is used for clean-up.” since our effect returns a Promise. To fix this, we’ll move the data fetching code to an asynchronous function outside the effect.


The final code will look like this.



To show how we can implement componentWillUnmount with hooks, let’s consider the following example where we create a event listener to check for the window dimensions after the component has mounted and removing the listener when the component is about to unmount.


First let’s create the functional component with just the state and jsx.


Next we’ll create the function used to update the states.


After that we’ll create an event listener using useEffect like we did using componentDidMount in the class component.


Notice how we set the second argument as an empty array for useEffect to make sure is runs only once.

Once we set up the event listener its important that we remember to remove the listener when needed to prevent any memory leaks. In the class component this was done in componentWillUnmount. We can achieve the same thing in hooks with the cleanup functionality in useEffect. useEffect can return a function which will be run when it is time to cleanup when the component unmounts. So we can remove the listener here.


The return of useEffect being reserved for the cleanup function is the reason why we got an error in the componentDidMount example initially when when we made the function inside useEffect async as it was returning a Promise.

The final code will be like this.



Finally for componentDidUpdate let’s look at this component.


In the above example we fetch a post once when the component mounts in componentDidMount and then every time the id gets updated in componentDidUpdate.

To get started on turning this into a functional component, let’s first write the following code declaring the states and the returning jsx.


Then let’s declare a function to retrieve a post.


Next we need to think about retrieving the first post when the component mounts. We can do this in a useEffect with the second argument being an empty array.


The component should load a new post when the ID is changed. The second argument in useEffect is a list of states for which the effect should run when once of them updates. So to run the effect again when the ID changes, we can add the ID to the array.


Finally your component should look like this.


As you can see we can take of the both the componentDidMount and componentDidUpdate functionality in one useEffect which cuts down on duplicating code.`

Wrapping up

I hope you find this post useful on how to achieve some of the functionality in class components in functional components. If you want to learn more about hooks, the React documentation has a great introduction to hooks here.

If you enjoyed this post please leave a like or two below!!!

Check out my latest post...

Making delayed network requests in React after state changes

13th September 2021