Transcript
00:00 Let's start with the easiest one. And that is down here with our footer. We want to make it so that we can lay out the message, so that the message can say whatever we want, rather than just accepting the full user. Before I do that, I'm just going to give you a little tip. What I would typically do for something like this
00:18 is, with the footer, we're accepting a user type. And so this user can have a name, and it can have an image. In a real application, you might have a whole bunch of other properties that are on the user. The only thing we actually are using is the name. And what this means is if anybody wants to use the footer, they're going to think that they need to have
00:37 all of these properties for the user. So if they need to query the database for the user or something, they're going to require all of these extra properties, when actually all we need is the name. So if this is the component I was going to build, then what I would do is I'd say pick, and then just the properties that I care about. Whoops. And that way, when somebody's looking at this
00:58 and they're trying to pass things, they're going to be like, oh, you just need the name of the user. Great, I'll give you an object that has a name property, and poof, that'll work. But we're not even going to do that. Instead, what we're going to do is take a footer message, and footer message is going to be a string. And then we'll take this, cut that and put it in my clipboard,
01:19 and then we'll put the footer message right here. So it's responsible for laying out the footer message. And if I come up to where we're rendering the footer, we're going to say our footer message, whoops, our footer message is equal to that string that I stuck in my clipboard. And we can reference the user directly
01:38 and not have to worry about the prop types or anything like that at all. And ultimately, that results in the same output, but the API for our footer is different. Now, we could make things a little different. We could say, hey, instead of a string, we can do a react, whoops, react.reactNode. And now, it still works.
02:00 The types all work and everything. But we could, with this, now say, hey, I want this in a span. And now that's a react node, and I can render whatever I like. Or we can leave it as a string. And that's kind of the point here is that you get to control still. Just because you're a layout component
02:18 doesn't mean you don't get to have some opinion over what types of things you accept. Now, you are kind of limited. You can either do a string or a react node that you don't have a whole lot of control. But I just wanted to make it clear that the layout component pattern doesn't necessarily require that you're passing react elements. But most of the time, you will.
02:37 Okay, so with that then, let's take another leaf node. So we'll go to the user avatar in the nav right here. So the nav has this home, about, and contact. And we have this reference right here. So we want to, or right now,
02:56 we're saying user image and user name. Instead, we're gonna just take this, and we're gonna say avatar as a prop that we're going to accept. So now we don't get to control what it looks like or anything like that. We're just saying, hey, I rendered the nav. You're gonna stick this where, you're gonna give me an avatar, and I'm gonna just put it
03:16 where the avatar is supposed to go. Avatar and an avatar is a react node. We come up here to our nav. We say our avatar is the react node. Again, we are taking this to a bit of an extreme. Some of these things, I think,
03:33 actually could be useful and good ideas, especially if this was a reusable thing and you wanted to customize that avatar. But again, in a server components world, this actually might be very useful because now if our app is the server component, then this can go talk to the database directly
03:52 to get the image or the user information and then render the image based on that user information that we got from that async component or whatever. So yeah, lots of value in that. But yeah, that takes care of that one. So now we're gonna go a little extreme with this main.
04:11 So then we'll come here in our main. We've got all these props. We want to remove these in favor of a sidebar and content. But before we do that, I wanna update the list. So the list, we want to make this except an array of react nodes called list items so that we don't have to do any of this logic
04:31 and like accept the function or the array of data or anything like that. Just make this a layout component. So we're going to take all this and render list items here. And then right here, we'll have list items, which is an array of react nodes.
04:52 I suppose actually react.reactnode might work just fine. Here, let's try that out. I think it actually will work because a react node can also be an array of react nodes. We'll take a look at that once we get there, but I'm pretty sure that will work. So here now I can say list item,
05:11 we want this to be list items, plural, because there are more than one. So list items, we'll paste what we had in there before. And yeah, react node is also an array of react nodes. So you don't need to specify an array there. So that's cool. We've got our list items right here, but then we can take things even further
05:29 with sidebar and content. So we're gonna say that this main is another layout component. And I'm gonna do this as content, content. And we'll come up here to our props for that. Content is a react node. And we'll actually, we'll get rid of both of these also.
05:51 And then we'll come up here to content, paste that in. And then we also are gonna take this, and this will be our sidebar. And say sidebar, and sidebar is a react node also. And up in our main, we can get rid of all this stuff. And say sidebar equals that list.
06:14 And so we're, yeah, just like layout components all the way down. But what's interesting about this is that now all of the state is up here managed by our app. That could get like super unwieldy in a really like huge app or something like that. So you don't necessarily want to do this everywhere. And it doesn't make sense everywhere.
06:33 But I wanted to take this to the extreme just so that you can experiment with it and get a kind of an idea of what is possible here. But yeah, now our main just accepts a sidebar and a content. And then we're able to render our UI right here. And then this list accepts list items. So then we can render our UI right here
06:53 and reference all of the variables that are in scope. And actually, you'll notice that our typing has got a lot easier everywhere. And so we didn't have to do any pluck or pick or whatever. They're just all accepting React nodes, which I think is, that's kind of cool.
07:11 I do see some value in this pattern for that reason. But it really, this is just something that you've got to play around with. And often what I say is like, how do you know how to do one thing or the other? And my answer is typically, you do them both and you choose the one that you hate the least.
07:28 So hopefully this is another tool in your tool belt for knowing how to structure your React components to avoid things like the prop drilling problem, to optimize React server components, and to enhance the reusability of your different elements of shared UI.
07:47 So that is the layout and composition pattern.