This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Class Components" Lesson
[00:00:00]
>> Let's go round at our details page. So we're gonna talk about class components now. So go to details.js. I'm gonna miss this but it was obviously it was a fun page while it lasted, but let's go make this a little bit more robust now. So this is gonna be like, all right, I clicked on Luna now I want to see a full informational page about Luna.
[00:00:26] So I'm gonna import component From react ,and I'm gonna import with router from React-router-dom So, let's remove details here, and instead of having a function represent a component we're gonna have a class that represents a component. So we're gonna say class, details, extends, component. So this is how you do what's called a class component, and class components have lifecycle methods and they work relatively similar to function components in many ways.
[00:01:10] But they end up being having some slight variations from here to there. And this is like the original way of writing React. React with hook is a relatively recent thing, it's only in the past two years probably that you've been able to do hooks with react. So the first thing that a class component always has 100% of the time, it always has a render method.
[00:01:35] The render method is going to work pretty much the same as your function body, it's gonna always return some sort of markup price, so something like this. In fact if you just saved this and went back over here and clicked on like Luna now right, this would work now, this is like the hello world, of a class component.
[00:01:56] It's just has a render method that returns something. Now some people prefer this and I'm gonna be completely frank with you, I actually like class components and I think that's kind of an unpopular opinion so don't trust me on it. I think the general react populist likes function components and hooks and all that kind of stuff, but I just like the how easy these are to use, I like how easy they are to read and understand later.
[00:02:25] Anyway, neither here nor there, they're both useful, neither one's going anywhere. Just use the tool that's best fit for the job that you're doing, right? That's why I'm teaching both of these is because you will see both and you'll have opportunities where something will be better expressed as a function component.
[00:02:38] And you'll see other opportunities like, hey, this actually be better modelled as a class component.
>> Are we doing this as a class component just to learn how class components work, or is it better in this case to use this as a class component?
>> In this particular case, it's pretty much just to learn class components.
[00:02:56] Let's talk about the next thing, is how do we create state? So instead of having hooks we have individual pieces of state. With class components, you actually have a state object that you're gonna refer to. So I'm gonna make a constructor here. This is a special kind of method for a class, this is not a React thing this is a Java script thing.
[00:03:18] This function will get run at the beginning whenever you create a new class or a new instance of a class rather. So the first thing that you always have to do whenever you do a class component constructor is you just have to call super. Just like that, React will yell at you if you don't.
[00:03:38] Why is this? Well, it's because you actually have to call the component constructor. And if you don't do this, this component constructor will not get called. So you have to do this. Then here, this is everything that you want to whenever you instantiate a brand new instance of your class, this is where you get to set up all the stuff.
[00:03:58] Most importantly, we're gonna say this.state equals, and it's gonna be loading true. So this is the default state. Whenever we create one of these, it's gonna be in a loading state, right? The next thing we're gonna do is we're gonna have an async ComponentDidMount. So class components have something called life cycle methods.
[00:04:28] So component did mount is the thing that gets called as soon as the React component is rendered for the first time. So as soon as someone goes to slash detail slash one, it's going to render this for the first time and then it's gonna call component did mount.
[00:04:43] This is kind of like the effect, right? That that use effect where we gave it the angle brackets, this is gonna get called once when it's first created and then it's not called again. So what we wanna do when this page is first called is we wanna go fetch all the data for the pet that we just tried to render.
[00:05:01] So we're gonna say const res equals await, Fetch, Yes, such, there we go. We wanna do with the backticks here, http://pets-v2- .dev-api's.com/pets?id=${this.props.match.params.id}. Now you might be looking at this like what did I actually just right there, that is so much staff I was not expecting. So let's break it down for just a second, this refers to the detail component right.
[00:06:04] It's the component that we are working on. Now that this these two match and params, this is coming from react router, the match and the params are basically, where are we? Here, so this is an app.js. We have the details:id, I need this, right? This is what I'm looking for and this is how React router lets you get at it.
[00:06:37] So if I'm looking for dog of id 3. This is where I'm gonna get it. It's gonna come from the match which is like the matched path. The prams or the parameters that I'm getting from the user, and the id is this whatever I call this, if I call this :dog, right?
[00:06:57] Then it would be .match.dog, right? It's whatever I called that.
>> If this was a function component would it just be props.match.params.id?
>> Yeah, if this was a function component, how would we get that? You actually use a special hook that gets it for you. Okay, so that's gonna grab that.
[00:07:20] We have to do the const json = await res.json. And then now I can say this.setState. I got a bunch of stuff here from JSON. And and I could do a couple of things here. I'm just gonna do something kind of easy. Well, let's shoot this way first.
[00:07:43] The first thing I wanna do is I wanna say loading is false, right? As soon as I've loaded this, I wanna set the loading state to be false because now everything is loaded, right? That makes sense. And this is how you do it. With set state, what it does is it takes this object that you're giving in emerges back with the state that you have.
[00:08:02] So in this case, I only have one set piece of state. But if I had like, other thing, If I did this, it wouldn't overwrite other thing, right? It doesn't object at assign. So it leaves the existing state there and it only overwrites what you have. Okay. Now what I wanna do here is I'm getting a bunch of state back from the API.
[00:08:38] And I could go back here and do exactly what we were talking about before, which is I need to do name and that's gonna be json.pets.0.name. So that's how this API works. In fact, let's just take a look at what it looks like. You can see here it has a pets array.
[00:09:04] So if there's multiple things that matched it, it will give back all of them. But it comes back in an array, right? So zero and then this is gonna be one Luna dog, Seattle, Washington description. It's kind of burdensome to go back and do all of those. So let me show you just a really fast way of doing that.
[00:09:23] So instead of doing all that we can do object.assign. Wrap those in parentheses. And then after that, I can say json.pets0. So what's happening here? We have this loading false, right? So that's going to overwrite that. And then everything else is gonna be passed in just directly from json.pets, right?
[00:10:03] So the name, the description, the images, all that, does that makes sense? Cool. So just to see what that looks like, let's just do a console.log (this.state). So let's go back here and look at this. That's not gonna work quite yet. That's true. So let's go make that work.
[00:10:43] We need to get this with route working with this component. So basically, by default, React router doesn't pass in all its information to the details component, we have to say, hey, please give us all that information we actually do need it. And the way you do that is you just wrap this details export at the end.
[00:11:05] So this one right here details withRouter like that. And this is just gonna now pass those props in. This is what again, called a higher order component. And now it's gonna pass all that information into details. It's kind of magical but like I said, it's just going to inject all the react router information into the route.
[00:11:35] Des it make sense? So now if I refresh the page with details one, you'll notice that the first time it logs, it's got loading true, which is what we expect, right? Then when it comes back again, and it calls this.setState here, that one, it's gonna re-render again with the new state.
[00:11:55] So then it calls a re-render again, and now we have everything coming back from the API, the animal, the breed, the city, the description, ID, images, so on and so forth. Makes sense? All right. So now that we have a bunch of useful information coming back from the API let's use it.
[00:12:24] Let's make something that looks nice. Get rid this console.log. Okay? Let's just destructure up here because this is gonna make it easier to work with I'm gonna say const animal, breed, city state, description, name, = this.state. Okay? Here we're going to make a div classname = details. And a div inside of that and that's gonna have an h1 with a name.
[00:13:27] It's gonna have an h2 with, Yes it's 2 that way. Animal again, we're gonna do one of those template strings. Animal breed, City, We're doing state, city comma state Like that. Then we have a button underneath it cuz we're gonna make like an adopt feature. So we do adopt, Name.
[00:14:32] Now, you might ask me and you totally get it done this way as well. This actually works line 30 and line 31 are equivalent. One uses a template string, one just uses like the native JSX way of doing it. It doesn't matter, you can do it either way.
[00:14:58] I actually couldn't tell you why I did it this way in my notes. Probably just force of habit. But you can intersperse these curly braces wherever you want to. Up to you, I'm gonna leave it this way just because that's where I use my notes, okay? And then under the button, we're gonna do a p tag with the description in it.
[00:15:27] Okay, so now if we pop over here, you can see, Luna so Havanese, you can click adopt Luna. And it's kind of like a little description of her as well. So why am I using object assign instead of, let's just write it out so you can see what it actually would look like, this.setState.
[00:15:52] Loading false and then you would be like name, Pets. See json.pets
[0].name and I'd have to do this for each one of them. Breed, Animal, so on and so forth for each one of them. No problem absolutely you can do it this way. Some people would prefer it cuz we're being more verbose and here's exactly what I'm expecting from the API.
[00:16:32] I'm 100% okay at this is what you choose to do. This was just lazy Brian writing lazy code. In particular, because I typically use TypeScript when I'm writing React and TypeScript catch all the bugs that I would normally face with this. If I'm not using TypeScript, I might be more prone to use something like this.
[00:16:58] Because here's precisely what I'm expecting. So, up to you.