Check out a free preview of the full Complete Intro to React, v7 course:
The "Effects" Lesson is part of the full, Complete Intro to React, v7 course featured in this preview video. Here's what you'd learn in this lesson:

Brian demonstrates using the useEffect hook, which allows developers to do asynchronous actions, to make an API request when the application first renders.

Get Unlimited Access Now

Transcript from the "Effects" Lesson

[00:00:00]
>> So far we've talked about you state, which I'm gonna say is like the one that you use the most, it's the hook that you're gonna use the most inside of react. The second one that you'll use very frequently is element called the Pet. Everything after those two, it's a long tail, right?

[00:00:17] You state and use effect 99% of what you need react hooks for everything else is a pretty specialized use case. If you do wanna dig into all of them, I teach all of the hooks in intermediate react and you can actually go through one by one and learn what each one of them does, okay.

[00:00:35] So let's head back to search paras for a second. I am gonna do use state and then we are gonna create, import another hook called use effect from react. Remember, when I was talking about don't do side effects inside of react, use effect is like a little. A function that you can like wrapped around something to say like okay here's we're gonna do things that are gonna call out to API's.

[00:01:02] Or do other kinds of stateful things are gonna live outside of your component and then we're also gonna import pet from./pet here. Okay, we're gonna have another piece of use state here. Const [pets, setpets] = use state and it's going to be an empty array So we're gonna call out to our API.

[00:01:32] We have like a little developer API that you can just hammer. It's just gonna return to you fake dummy data of pets that you could adopt, right? And here underneath all of this, we're gonna do a use effect. And when I give that a function In this is a function that's going to be called outside of the render, right.

[00:01:55] So basically you're registering a function to be called later as essentially what it's doing. Kind of like a an event listener, right? Where you're not executing that function right away. You're waiting for something to happen first, are you waiting for a click or key up or something like that?

[00:02:07] That's what an effect is basically saying like to finish my rendering function. Then call my effect which will, go fetch some data from an API and then come back. Okay, and we're gonna make a function here called request pets. That's gonna go out to an API and then that's is going to call set pets.

[00:02:35] Now, how often do we want to call request pets? Well, for now, we just wanna call it the beginning. Eventually we're gonna have it whenever they submit the form, right? But for now, we just want it to whenever a page loads, just take, whatever my data is. I make a request of the API to go get all the pets.

[00:02:55] So you can give it this array of dependency variables. So here I can put here, call this effect again whenever blah happens, right? So if I put, for example breed, this would call it whenever breed changes, right? So that's what this array is. It's an array of dependent variables.

[00:03:18] In our particular case we just never wanna call it once at the beginning so we wanna call it exactly once after the first render. So if you just give it an empty array that's what it's gonna do that makes sense. If you give it nothing it's going to say hey if anything changes.

[00:03:34] If location animal breed pet if any of that changes then call it again that would be way too much right we'd be having our API unnecessarily. So for now just give her an empty array, they're gonna write a function called async function request pets here we're gonna call an API so const.

[00:04:01] Res as in response equals await, fetch. And then we're going to give it this HTTP colon. So I do this over HTTP and not HTTPs for the sake of this class that you don't have to worry about. Cores are or not cores but necessarily but like SSL errors this is just simpler if you do it over HTTP.

[00:04:28] Pets-v2.dev-apis.com this is a set of serverless functions that Frontend Masters and I maintain. That's just like a dev API for you all to play around with. We're gonna call the pets API, and we're gonna say animal =. Animal, If you're not familiar with this dollar sign curly brace, this is just a, it's called a template function.

[00:05:02] It came with like ES6. It's pretty old. Now it's like from 2015, but make sure these are back ticks as in next to the one on your keyboard or that's this won't work, okay? So animal equals animal and location equals location. And once we have your breed equals breed so this is gonna call to the pets API.

[00:05:37] It's gonna go grab this and it's gonna bring it back And then here, you're gonna say const Json = awaitres.Json. This is just how fetch works. It's like a browser API, if you're not familiar with it. And then await is basically saying this is gonna take some time to do, so wait for this to happen first.

[00:06:01] And then do this fetch gives you back a promise right in a way just says wait till this promise resolves. What you do this instead of like callback hell or doing promise.then this is just a simpler way of doing that. Okay, and then after that you're gonna say set pets Json.pets.

[00:06:22] And then now we're all happy with going out to the API and getting that and this will get called once after the the app is rendered the first time okay. And then here underneath the form so wherever the form ends here. We're just gonna make a quick pets.map.

[00:06:48] Pet and then this is gonna just be pet name equals name.pet, or pet.name rather. Pet.name animal equals pet.animal, breed equals pet.breed and then key. Do you remember that I had you and I did it up? Here's one I didn't explain it but like key is basically saying like, hey, I have multiple of these pet components in a row.

[00:07:25] What happens if pet A and pet B switch spots. If you don't give react to key it can't tell that so it just destroys both of them and then re renders them totally from the ground up. If those are like big complicated trees, right like they're huge components that have lots of interactivity and stuff like that.

[00:07:44] That can be pretty costly, right? So a key doesn't say like I'll check to see if, this is Q1. This is Q2, and if I can see that now, it's 21 is like, cool. They just swapped, and you just swap some for you, that makes sense. Okay, that's what he's for.

[00:07:59] So the key to key, if you will, which maybe you won't, is it has to be unique per pet, right? So, for example, pet.name, there's a lot of Fidos in the world, right? So that's not a unique identifier per pet but the pet.id which is a like a database key.

[00:08:17] Or something like that is people wanna put indexes here sometime that's generally not a good idea why is that because. If two things swap, their indexes won't change, right. So it'll think that nothing changed, which is a big problem because something did change. It's better to be just like not have a key in that case.

[00:08:42]
>> Had ideas from the API.
>> Correct? Yeah, the pet ideas from the API. So as the creator of this API I guarantee you it is unique or famous last words I don't know it's your problem not mine. [LAUGH]. So you should have an ES lint error here here right there.

[00:09:06] Use effect has a missing dependency request pets. So this is where I get annoyed at this particular rule. And it's a warning to be fair it's actually an error it used to be an error and I was even more upset by that. It does its best to see like hey you're referring to request pets which is a thing that is defined locally.

[00:09:30] So it assumes that comes from a hook now if this was a hook and then yeah, like if I was saying console.log breed. Then I would wanna put breed here, but request pets is just a function. So you have two choices here. You can put request pets here and this will satisfy it.

[00:09:47] That's new. I'd actually didn't know that. So now it's certainly yellow. She's like this. You're a function you should be moved inside of this So I guess you could do it this way. And then you have to put, okay? So this is like a cascading thing. Now we're referring to animal location and breed in here, which we actually don't want it to be dependent on that, right?

[00:10:10] Because we want people to be able to type without really requesting the API. So, in this particular case, what I'm gonna tell you then is to just ignore it or you can say.//eslint-disable-line. And you can just do that totally wholesale. This led to prevent it from giving you any error which I maybe advise against cuz you might have different errors on here.

[00:10:38] So you can actually specify react-hooks/exhaustive-depths. Now, it's specifically only going to ignore that one error. I show you this specifically cuz I end up doing this a decent amount. Because this is a little bit more like, frequently you wanna be aware of this, but not always, right? As opposed to, never put use state or any hook inside of an if statement.

[00:11:07] That's a hard error you should always change that this one if you know what you're doing then go ahead and ignore the warning. And again it's a warning so you actually never have to fix it just yellow squiggly lines really bothering me in my code. When a guy cannot even write, so that's why I do that, okay.

[00:11:30] I have a note in my code. Because we did async here. This is where you might see an error about the regenerator runtime. If you do that your browser's list is incorrect. So whatever you have here sorry, I didn't even say that. So that's a problem. So I probably would get this.

[00:11:50] Let's even see if I can get it cuz then I'd be able to show you what the error would look like. Looks like it's not doing it. It's too bad. I wanna show you what the error looks like. Anyway, not a problem. If you're seeing an error about regenerate a runtime here.

[00:12:12] That means you need to delete your cache, delete your disk folder. So delete this here, delete your disk folder, maybe delete your node modules. Make sure that your browser's list which I went over before is correct which is should be like last to Chrome versions like this, And then you should fix that again.

[00:12:41] But hopefully most of you aren't seeing that. Now you should be seeing something coming back from your API. See see Luna Bunnashabhain Olive pseudo beam, all of these here, that should be coming back from the API. And if you look at your network tab here in your browser, you can see here this pets API.

[00:13:02] So you can see it's coming back to android, okay. And you can see the response here it comes back with ten pets. They look like that. They even have little images which we'll put up here in a little bit. So closures, let's talk a second about closures. Notice that we're using request pets inside of search prints, why is that?

[00:13:31] It's wasteful because we're creating a new function every single time. That we re render not ideal. Not a big deal. The reason is that, we're using closure. So now that anytime, this animal refers to precisely this animal all right. That's helpful because so that we can actually just use closures like functions that can point to the internal state of something.

[00:13:54] To reference these exactly so that's helpful, that's why it's inside of it. You might ask why didn't we just put this body inside of here this request pets inside of us effect one. I wanted to make an async function this function here cannot be async. It's gonna tell you why I think In fact callbacks are synchronous to prevent risky conditions, that's no good for them for warning you about that.

[00:14:23] So you just make a function and then just have a call and that's totally fine okay, Yeah and then at that point, we're just calling an API, getting something back from the API, setting a use state hook, and then we're rendering it down here. So the first time this renders, and this is a positive thing, it's gonna render once with nothing in there, right?

[00:14:48] The very first render, this is gonna be an empty array. So if you notice it'll render once very quickly it then renders a second time with the pets cuz the API is fairly fast right. But imagine this was a very slow API yeah suffice to say that it renders once nothing in there call it.

[00:15:16] Then schedules here at this use effect to call the API after the first render he calls the API. As soon as this resolves you can see down here called sets pets as soon as you sit call set pets. This is also signifying to react hey a thing changed reacts a thing changed and then it goes back and re renders again but now this is not an empty array.

[00:15:35] This is an array full of pets back from the API, which is where we get all of our pets. Does that cycle make sense? This is preferable because if we just wait for the API to come back, the user has to wait to see anything until that first call comes back which, we're on fast internet.

[00:15:57] Or many of you I imagine are probably on pretty fast internet that this happens really quickly. But imagine like you're in you know 2G In like rural North Dakota or something like that right that first API call could be really painful to wait for. So the person is stuck there staring at nothing as opposed it's nice to look at something.

[00:16:16] There's a lot of research that shows that people can't even make a decision that fast, right? When they look at websites, so they look at something and then if you're requesting things in the background. They're still processing the layout of your UI, then they'll start seeing the actual data come back right.

[00:16:31] So we're kind of getting into like human psychology of user interfaces here but this is better even if it requires more processing and code to accomplish