Transcript from the "Component Composition" Lesson
>> Right now our search params page is getting quite long. It's we're up to 90 lines of code. There's no hard and fast rule for how long these can be. But if you're at 1000 lines of code, you might want to reconsider some of your life choices. In general, the idea is that you wanna have one component handle one thing, just in general, right?
[00:00:22] You want it to, this one in particular like you want it to be like the page. Then you want to like delegate everything out to smaller components. So like a good example of this that we did is we have this pet component and all this pet component does is worry about being a pet, it doesn't worry about doing anything else.
[00:00:37] And now it becomes reusable as well as like if I have pets in multiple places, I can drop those pet components in multiple different places. There's lots of benefits to doing it this way. So, one of the things we could do is we could we have multiple these like labels and selects, we could abstract that into like a label control component or something like that.
[00:00:58] We're not, I'm not gonna do that because I think for now, this is totally fine, but that that would be a place that you would consider decomposing this larger component into two smaller components. The one that we are gonna decompose into a smaller component is the bottom half of this page is like the results right?
[00:01:16] So it might make sense for us to abstract that into like a results page, and then we could have that render here. So what I'm gonna do here, I have my pets right here. I'm going to right click on this. And I can click refactor. I might have to do it this way.
[00:01:48] Sometimes this works. All right I'll just put it in a diff here. So I just wanna show you one of the coolest capabilities that all I did was wrap the pets in its own div. Notice there's a little light bulb here. One of the cool things that VS code can do for you is I can actually say, Extract to function in module scope.
[00:02:18] And this actually abstracted basically into a new thing, and then I can just move this across or we can actually even get a little bit faster than that. This used to work in closing scope now. So that's one thing you can do, you can actually have it extracted out for you.
[00:02:41] In this case, it didn't actually help us that much. So I'm not gonna do that. Step what I'm going to do, I'm going to read these divs and we're just going to copy or cut it out entirely. So I'm just going to cut that and we're going to put something here called results.
[00:03:00] And we're just going to pass the pets into it. Okay. We create a new file here as you might guess we're going to call it results.js and we're going to. Import pet from ./pet. And then const. Results is gonna be = (props), And we're going to return blur and at the bottom be sure to export, default results.
[00:03:54] And then we're going to. Well, yeah, so we have the props here. We know the thing that we want out of the props is called pets. So an easy thing you can do here is I can put curly braces inside of this and I can structure as pets.
[00:04:12] So this is going to pull out of this props object, something called pets and call it pets. So now I don't have to say props.pets. I can just say pets makes my code read a little bit easier. So I'm gonna make a div here. And it's class name is going to be equal to search.
[00:05:07] So h2, No pets found. Then after that colon again parentheses, so if there's no pets found render this if there are pets found then do or do pets.map. Pet. Can do the same thing here because we've been doing a lot. Pet. You can do the destruction here as well.
[00:05:46] So if you wanted to change pet to, animal blah blah blah. I'm not gonna do that I'm just gonna do pet. Animal=pet.animal, key=pet.id, name= pet.name, breed=pet.breed, images=pet.images, Location equals and then we're going to do a template string here. So backticks remember Pet.city, pet.state. So the API gives it back to us in city comma state.
[00:06:41] And we want to give it back to the API or to the pet component as like one long string that's like city comma state. And then the id=pet.id. Couple of things here and then we'll close it off. So yeah, let's talk about a couple of things here. One something that people might ask is like I'm already giving the pet the id in the key place.
[00:07:12] Can't I just refer to the key place? And the answer is no, key only is used for react, keeping track of changes, right? So it actually removes that can't when it passes it down to you AKA you cannot have a prop called key ever. There's only a few that are reserved key is one and children is the other.
[00:07:33] I don't think we talked we'll talk about children later. But suffice to say you can actually pass down like components right rendered components inside of something called children. So that's why you have to separately pass down pet.id. Now, I'm just going to show you don't you don't have to type this in.
[00:07:53] I'm going to show you the lazy way we could have done this. That's a bad idea. So, if I typed it in this way I could have done dot dot dot pet. And then I would have also had done key=pet.id these would have functioned similarly. So this is called the spread operator.
[00:08:16] And JSX is just going to take this object and spread it across that. So instead of having to do these all individually this would have just done that like is spreading across the entire object that got from pet. Unless the component is actually meant to be ignorant of all the properties being passed in, don't do this.
[00:08:36] And let me tell you from deep experience with this problem, it makes us so much harder to read later. Because I'll come back here is like what the hell is pep getting? I don't know, right you become unable to understand. How the parent is interacting with the child by reading the code.
[00:08:52] Yeah, I now have to go into pet to figure out what it's expecting.
>> Does this only work if the key values are the same? So if the problem is name and the API is returning name.
>> Correct yep, so it'll only work if these things won't are named the same thing, which actually, location wouldn't work because we actually renamed location to something else and that the API does not give that back to this location.
[00:09:20] So this is exactly what I'm talking about is like the waters become very murky of what's going where and are we getting the right things in the right locations. So I wanted to show you because you're never really going to run into this because this looks so nice and so easy to type.
[00:09:34] But just don't do it believe me, having worked on a code base that did this a lot. It was incredibly frustrating to work with. Just stick to this, I know it's verbose and takes so many keystrokes in my fingers are so tired and please help me, but don't just, don't do it.
[00:09:53] It's a terrible excuse for that. Okay, so go back to search branch really quick. Let's just kind of wrap this up and make it work, we have results here, but we have to import it at the top. So we stopped using pet because pets now only used in results.
[00:10:11] It's not using search params. So you can say import results from ./results you deleted pet up here and then down here at the bottom, underneath the form, you put results pets=pets. Now, if we go back over here, now we have like a nice little search box over here and we added some more CSS and structure to it.
[00:10:33] So, that's why that works now.