Current section: Side-Effects 29 exercises
solution

Effect Cleanup

Loading solution

Transcript

00:00 Let's start out by demonstrating the problem. So here we have our use effect. We're adding an event listener, and we're not returning a cleanup. We also have a console log, so we can see when the event listener is being called, and we can add one for when it's being cleaned up. But here we have this huge amount of data that we are logging here.

00:19 It's 1 million items of an array, and filled with our dog, cat, and caterpillar emoji. So it's just a lot of data. And now if I save that, and let's come over here to our more tools and task manager, and you'll notice we've got all the different tabs

00:39 that we've got open. And here's the tab that we are interested in. So 73 megabytes, not a little, but it's not terrible. If we open up our dev tools, there's this memory tab that you can go to, and you can scroll down here and see how much of the memory allocated to this tab

00:58 is our JavaScript objects that we have running right now. So you'll notice it kind of goes up and down as garbage collected and different things like that. But because we have this huge data being allocated, and then we have this function that uses that huge data,

01:17 and then we never clean up this pop state listener, that function is never garbage collected, and neither is any of the other stuff that it's accessing. And so if I uncheck this, we don't see anything go down by any significant amount. We check it again, and now we're gonna start seeing stuff go up really quick. So I'm just gonna keep going back and forth,

01:38 boop, boop, boop, boop, boop, and we are allocating a million items in an array with three emojis each. And you'll notice eventually we're gonna take more memory than our entire browser, because it just keeps on going forever and ever and ever. So this is the danger of a memory leak,

01:56 because you're not cleaning up after yourself in a use effect. We're using so much memory. Here, let's see if we can get to a gigabyte while I explain some other things. So, yeah, it's not necessarily like users aren't gonna come over here and they're gonna say, I'm gonna go forward and backward and forward and backward like a million times.

02:14 No, it's that you could have 300 of these elements or these React components added to the screen, and if each one of them sets up some sort of subscription and never cleans up or whatever, then maybe an individual one isn't a lot of memory that it's hanging on to,

02:33 like, oh, these are the variables and whatnot. But all of them together multiplied, yeah, that can add up pretty quick and can result in a slower user experience than you would like, I'm sure, because especially mobile devices only have so much memory that they can allocate to their process.

02:51 So, it'll just make everything slower by doing this. So, for that reason, it's very important that we fix this. So, I'm gonna move this over. We're gonna refresh the page, get rid of all of that nonsense. We're back down to a reasonable amount of memory, and I'm gonna leave this huge data stuff in there so we can see the effects of what we're doing.

03:10 Okay, so we're going to extract this event handler and we're gonna call it, yeah, handlePopState. You can call it whatever you want. And then we're going to return, whoops, return a function that removes that event listener,

03:30 popState, handlePopState. So, the reason we had to extract it to a function is so that we can pass the same function to popState. So, here's the function I want to subscribe to, and now I wanna remove it. That's what's going on here. And with just that change, we can observe the impacts of our changes.

03:50 We can also, if you want to, we'll add a console.log cleaning up. And that way, we can take a look at our logs right here. We can clean up, boom, there we go. And so, we can see that it is cleaning up. And if we take a look at our memory tab and bring over our task manager again,

04:09 then I go back and forth, boom, boom, boom, boom, boom. And you'll notice it'll go up for a little bit, and then a garbage collection will happen, and all of those millions of items in that array will get removed. And so, it stays at a perfectly reasonable amount of memory.

04:26 You'll never get it up to a gigabyte of memory because we're cleaning this up properly. So, that is why cleanup is so important. You're not going to face this a ton, but the other thing that is a problem if you don't clean up is that all of the stuff that's happening inside of this event handler will continue happening

04:45 even though the component no longer even exists. So, you'll be calling set query on a component that no longer exists. React actually used to give you a warning for this just to say, hey, you might have a memory leak in here, but it resulted in too many false positives. So, they don't really do that anymore. But yeah, this is definitely a situation

05:04 where you can have a memory leak and you want to avoid that. So, yeah, make sure you're always handling cleanup or at least think about it. You don't always, not every use effect needs to have a cleanup. It's not like a for sure thing, but most of the time they do. And so, just make sure you at least think about it. Like, what needs to be cleaned up here?

05:23 What part of the external world am I mucking up? How do I clean that up when I'm done? So, there you go. Cleanup, it's important, folks.