DEV Community

Cover image for Are you taking care of memory leaks with the useEffect hook?
Nihar Raote
Nihar Raote

Posted on • Originally published at

Are you taking care of memory leaks with the useEffect hook?

This article does not tell you the benefits and drawbacks of the useEffect() hook nor is it going to persuade you to use React Hooks. The fact that you clicked to read this means you already use Hooks but want to make sure you're cleaning up resources and canceling all requests and event subscriptions properly.

If you're still undecided whether to use Hooks read this article. To learn about cleaning up with the useEffect() hook, continue reading.

What makes useEffect different?

In a class-based component, there are three lifecycle methods that are invoked when a component mounts, unmounts and is updated. They are componentDidMount(), componentWillUnmount() and componentDidUpdate() respectively.

A functional component that uses Hooks has useEffect() handling the work of these 3 lifecycle methods. Although this gathers things in one place, it also raises the complexity of this Hook. If you do not know what you're doing, it is easy to end up with a component that keeps updating endlessly.

You can read this article and learn how to not commit this common mistake. There is no need to know this Hook inside-and-out, you can get by with knowing just enough. But knowing more can't hurt.

The article gives a lot of information on the useEffect() hook.

But it is very long. I suggest you grab some water or a cup of coffee, settle down, and take some notes while reading it. Although it's lengthy, once you get through it, your understanding of the useEffect() hook will improve.

Let's see how to clean resources before a component is unmounted with the help of the useEffect() hook.

Cleaning up after a component

To set up some event subscriptions or request data from an external source, you only need to add them in the useEffect() hook.

Subscribing to an event

Here, we set a click listener in the useEffect hook. This event listener will register when the component mounts.

To remove this event listener, we need to return a function. The useEffect() hook will execute this function right before the component is unmounted.

Cleaning subscriptions

Here, I've named the function clean(). This clean() function will execute and unsubscribe from the event right before the component is unmounted.

It does not matter what you name the function nor does the function need to be a named one. You can return an arrow function if you want.

Wrapping up

This article is aimed towards specifically avoiding memory leaks by closing any requests still running and terminating any timers, etc that are still executing. Although this means you prevent an unmounted component from occupying resources, that is not the sole cause of memory leaks.

Like I mentioned previously if you don't apply useEffect() properly you will end up with an unending loop of updates. useEffect() is a powerful hook, but it is just as difficult to get used to. Here is the link to that article again. Knowing how to make full use of this hook will save you hours of debugging.

What do you think about the useEffect() hook? Do you find lifecycle methods easier to use? Leave a comment below.

Top comments (2)

king11 profile image
Lakshya Singh

I feel like hooks are more peformant because we can specify for particular dependencies they need to observe as compared to class functions . I don't know if am right πŸ˜… just a react noobie

napoleon039 profile image
Nihar Raote

I'm far from anything resembling an expert. I consider myself a React noobie as well πŸ˜‚. And I like that about Hooks too.

When I started learning React and came across state changes using setState, I thought it was a hassle but later got used to it. When I saw how Hooks worked, I just stopped using class components completely. I don't think I've ever used class components in the last month.

I have no idea about the performance factor though. I think I read somewhere that the performance is not that different, and it depends on how we use it. But I could be remembering wrongly. I hope someone corrects or confirms this here.

If there is a performance difference, I might write an article on it.