Imitating react life-cycle methods with useEffect hook

Sudeep Gumaste
The Startup
Published in
3 min readMay 17, 2020
Thanks to Filiberto Santillán for this photo on Unsplash :)

It’s been a while since React v16.8 has been released. One of the most important features that was added to React with this release was the mighty hooks. With hooks you can turn the dumb state-less components to smart state-full components. Hooks are incredible but they for sure have changed the way we as developers need to think about the components. One thing I have seen a lot of developers struggle with is the useEffect hook. This one hook alone can somewhat replace the good old life cycle methods that were accessible with class-full components. This article of mine is an attempt at imitating some of the life-cycle methods with useEffect hook and hopefully give you an idea of how to use it accordingly

What it does?

This is what the official documentation has to say about useEffect hook

The Effect Hook lets you perform side effects in function components

useEffect fires the callback function as a result of something changing in the component. In other words the callback is fired as a side effect of something changing in the component.

useEffect example

In the above example, the document.title changes as a side effect of count changing.

Note : Just like any other hooks, there can be multiple useEffect hooks in one component and all the useEffect hooks are fired when the component mounts the tree.

Now that we have a rough idea about what useEffect does, let’s now look at how to use it to imitate life cycle methods with it

componentDidUpdate()

This function runs whenever something in the component changes. This is the default behavior of useEffect hook if you don’t provide any dependency array, it fires the callback on every update.

useEffect(()=>{
console.log('Component updated')
})

BUT it offers better control with the help of dependency array. Dependency array is where you specify what variables does React need to check and see if they’ve changed before firing the callback.

Consider these examples below:

useEffect(()=>{
console.log(`count updated value ${count}`);
}, [count])

This useEffect only fires the callback if count is updated

useEffect(()=>{
console.log(`Either count1 or count2 has been updated`);
}, [count1, count2])

This useEffect fires the callback when either one of them or both are updated.

One more thing that you must keep in mind is NEVER update one of the dependencies in the hook. It’ll result in an infinite loop. Just like when you call setState in componentDidUpdate.

//Never do this
useEffect(()=>{
setCount(count=>count+1);
}, [count]);

With these examples you might be wondering, “what if I provide an empty array as dependency array?”. That’s exactly what we’re gonna do next!

componentDidMount()

This life cycle method runs as soon as the component mounts on to the DOM tree. This method is usually used to fire functions that fetch data and store it into the state. You can imitate this with useEffect by providing an empty array as dependency array.

useEffect(()=>{
Axios.fetch('https://jsonplaceholder.typicode.com/todos')
.then(res=>setData(res.data))
.catch(err=>console.log(err));
},[]);

We can cleverly hack it and make it run only the first time the component mounts the tree as a result imitating componentDidMount().

If es-lint gives you a warning for providing an empty dependency array, silence it by adding //eslint-disable-next-line :P.

useEffect(()=>{
Axios.fetch('https://jsonplaceholder.typicode.com/todos')
.then(res=>setData(res.data))
.catch(err=>console.log(err));
//eslint-disable-next-line
},[]);

componentWillUnmount()

This life cycle method runs right before the component is about to unmount from the DOM tree. This behavior of componentWillUnmount makes it suitable for writing cleanups. If you have attached any eventListeners or say you’ve subscribed to an external API, this is where you are want to clean them up. You can imitate this with useEffect by returning a cleanup function in the callback passed to useEffect.

useEffect(()=>{
const timer = setInterval(()=>{
setAccessToken(getNewToken(refreshToken));
},5000);

// this runs before the component unmounts just like
// componentWillUnmount
return ()=>{
clearInterval(timer)
}
}, []);

And that’s how we imitate the life cycle methods with useEffect hook. If you noticed any error, please comment down below and I’ll rectify it. I hope this helped you. Thank you for your time and have a great day!

--

--

Sudeep Gumaste
The Startup

Leveraging front-end mastery and full-stack expertise, with a nuanced understanding of web3 | https://sudeepgumaste.github.io