This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "useEffect" Lesson
>> So let's date let's move on to effect for use effect. So you can see here, this is just a clock at the moment, right? It's just counting up. It's currently 10:21AM here in kind of hazy gray Minneapolis. So let's go over what this is actually doing. It's using state, so we're using new state again.
[00:00:25] And then it's just creating the current date here as the initial state. And then it's doing a timer here, which is a set timeout. And it's setting the time so it's calling the set time on use state with the new date every one second, right, so basically it's just advancing the clock every second.
[00:00:47] Okay we'll talk about this in just a second ignore that line but that's what use effect is doing is is basically creating a side effect for your particular component, right? We couldn't do this inside of the render because we want this to be scheduled outside of the rendering cycle.
[00:01:06] And then every time that we call set time from use to here, react knows, something has changed. I need to rerender. So that's what it's doing here. Every second it's re rendering the clock so you could do things like make this like render faster than that which would be pointless because this isn't always going to change or we can make it change slower than that so you can see it'll start skipping numbers here.
[00:02:04] This is basically where you wanna do things that are outside of like your normal render cycle. So if you're coming from like an older version of React, this is where you want to do like component did mount things, component will unmount, component did unmount, those kinds of things are gonna be kind of located inside of Effects right?
[00:02:20] Which is what that use effect function here is doing., Okay, and then something else this using effect is doing, is you notice that it keeps getting run over and over again, right? It's getting run every second. Why is that? Well actually didn't give it any dependencies so basically anytime any of the hook data changes in this it's going to schedule itself again, right?
[00:02:49] As opposed if I give it this notice is actually going to stop counting because this means it's gonna run once now keep in mind that anytime that I type in this code sandbox automatically restarts everything so if I just start putting something in here notice it will update Right, and that's just because code sandbox is runs it every time that I type something in here.
[00:03:14] So that's what this is doing this is a an array of dependencies. Now if I put time back in here, this will start updating again, why? Because now it is updating every time that time updates, which is every second, right? Which is why this is keeps getting rounding every single second but if I put like set time in here, set time is not changing.
[00:03:39] It's just a function right? So this then stops updating again. So actually the better way to write this would be time because this has an explicit dependency on time. If I then later go back and add more hooks, it'll still only be dependent on time. So it's better to be explicit with your dependencies right or when you want this effect to run again.
[00:04:00] Because if I just leave it off, it's implicitly saying run this whenever anything changes, which works for this because I just have one other use state hook in this but if I ever expanded the scope of this then it would work differently which could be bad. Okay let's talk about line eight here whenever you're running a Timer right so you're basically scheduling yourself to run a second in the future what happens if I unmount the component in the middle of that this this timer is still scheduler is still going to run in the future.
[00:04:39] So clear timeout allows you to just take in whatever the result of set timeout is set timeout gives you back a number that corresponds to the timer that you're actually running so if you actually look at. Console.log timer. I think this just ends up being a number right?
[00:04:57] It is right. So this is just a number that's getting put out here. But if I say clear timeout with the correct timer number here, it'll prevent the timer that I scheduled from running. In other words, this function here that you return at the end of an effect Is what gets run to clean up the component.
[00:05:14] So if I later go and unmounts the effect component, which you can see my code base, I actually don't. So it's kind of unnecessary, but if I did, I would want to clear that timeouts so that I was not calling set time when this component went out of scope.
[00:05:31] Now is it a big deal if it actually does run? No it's not going to really change that much but imagine if you were doing maybe heavy computations or something like that and you wanted to cancel that because you unmounted the component and that computation is no longer effective.
[00:05:47] Or maybe you have like some components making like a sequence of API requests and you want to like interrupt that sequence right there's a bunch of reasons why you'd want to clean that up or another good reason. Let's say I had to write a component to connect react to a jQuery like, I don't know, like date picker or something like that, right?
[00:06:08] The way you would do that is you'd actually control that here and then from an effect, whenever you had to unmount that component, you'd use that to clean up your jQuery, right? Otherwise you're gonna get memory leaks. 99 times out of 100 that's even go with 999 times out of 100.
[00:06:25] You're doing this so you don't have memory leaks, right? That's what most of this like returned function is cleanup stuff is for It's to prevent memory leaks. Kind of an advanced use case but you chose to watch intermediate react not me. [LAUGH] Any questions?
>> Is that comment specific to the use effect hook then?
>> Is the only the clock we rendered or the whole page?
>> Only, so React is really intelligent about what it chooses to rerender. So in this particular case it is only the effect component that's being re rendered right so it's not like for example this use state one is not being re rendered because React is smart to see like okay the effect had a state change, right?
[00:07:14] Because I know data doesn't flow up right cuz of one way data flow. I can just rerender the effect component and leave everything else as is. That's a good question. Yeah,
>> The effects are called a second time does the first timer clear?
>> No, so it's been called every second, right?
[00:07:38] But I think I can see what the person's asking is like, what happens if there's overlap, right that it runs again before cuz another hook could change or cause it to render again. There's nothing here that would clean up that code right, there's nothing here that would prevent it from running which means you could definitely run into race conditions there.
[00:08:00] In which case you just have to be like more defensively coding to make sure that your race conditions don't race, is that how you say that I think so, I'm sticking with it. Yeah?
>> I do have a bit of a tangential question since we just mentioned race conditions.
[00:08:40] It doesn't seem like that's ever come up here, but so far, obviously we're doing simple things. In a general sense do you find do you use like await async await a lot to deal with those things or how does react So, what tools or how would you approach kinda timing things like that?
[00:08:56] I'm sure.
>> I mean I think the you can kinda distill that question down is like I have to do a synchronous orchestration, right? And there's several very valid approaches to that. If you have like very complicated workflows, we're gonna talk about Redux later, that's actually where Redox really shines.
[00:09:16] You can do things with Redox sagas that make it really nice to visualize. Do this, do this, do this maybe do this, maybe do that, right. That's is the use case of Redox, that is if you need to do stuff like, that if it's really just do a call, wait get the answer do a second call writing an async await function is gonna do that just great.
[00:09:45] Yeah, I think that that's I'm satisfied with that answer.
>> I appreciate that.
>> Yes. Any other questions? It's good for you to really understand state and effect. Cuz those are by far the two most used hooks everything else is a pretty long tail. Have you ever seen like the pattern of usage with language where there's the word that's used the most and then there's these worthies the second most and third most it's like this curve that goes on to a really long tail and it applies to way more things than you think it should.
[00:10:18] Definitely applies to hook right there's like state here effect here. Maybe reducer because there's people that missed Redux. And then there's like a long tail after that right? Or context maybe I don't know one of those. Yeah, that curve definitely applies here. Yeah, Mark.
>> If I didn't use use effect, but using set timeout, how can I clear the timeout and prevent a memory like.
>> You can't, Or you shouldn't because that would be creating a side effect in your render function which is don't, please God don't [LAUGH]. The point of use effect is to contain side effects, right? And if you're asked me is like how do I contain a side effect without the thing that contains side effects, right?
[00:11:06] That's, you can't or you shouldn't he probably could figure out a way to do it and it would be a bad idea. There's other functions we could use here like layout effect that technically would be able to handle it, but he would be bending the tool to use it in the wrong way, right?
[00:11:22] It'd be like using a screwdriver as a hammer
>> Is it common to update the state and use effect and also have that state in the dependency array?
>> Yes so the question is is here we're updating time right we're using set time and we should have here time like this.
[00:11:43] That is a really good rule of thumb here if you see your self referencing either by setting it or reading from almost always is going to be a dependency down here in your dependencies. It would be the exception that it would not be down there. So there's a ES lint rule called the React hooks rule put out it's an official ES lint package from the React core team and it actually enforces that you do that.
[00:12:14] So actually, if the ES lint rule would actually require me to put in here set time as well. Stop that, there we go set time. Cuz technically if set time changed, it would also fact that it won't because it's a function and it wouldn't do that but the ES lint rule would require you to down here to put that yeah that's that's a astute that's a good observation.