Transcript
00:00 Let's talk about composition and the composition and layout components pattern. This of all of the patterns that you're going to learn today, this is probably the most generally applicable wherever you're working as a product engineer, as a reusable components engineer, whatever, you're going to be using this pattern quite a lot,
00:18 especially in a React server components environment where you have server components and client components that need to compose together nicely in an optimal way. The composition pattern is definitely going to be one that you want to understand. So let's talk about it and then we'll get into the exercise.
00:35 Here's the one-liner, the composition and layout components pattern helps to avoid the prop drilling problem and enhances the reusability of your components. Okay, what is the prop drilling problem? You can come take a look at my blog post about prop drilling that will explain it in depth. But to be brief, we have this component that is managing some state or something.
00:55 We have this child component that accepts those as props and sends them along to its grandchild, and the grandchild accepts those. That's the basic idea of the prop drilling problem is that this child right here doesn't
01:10 actually know or care anything about the props that it's receiving. It just is forwarding those props along. This is not necessarily a terrible thing. It's really often not a big deal, and in this particular case, I probably wouldn't change anything about this code if I was shipping this to production.
01:30 But if you've been working with React for a while, you definitely have seen situations where this can be a problem. And so, yeah, it can cause some issues. And in particular, when we're talking about server components and client components and composing those things together in a nice way, yeah, this is pretty much a requirement for using that feature efficiently.
01:51 So how do we solve this with composition? Here is maybe a little bit overboard example of how to deal with this problem. So now the app, for some reason, we have to maintain that state up there. And the app is going to render the child as it was before, but then instead of passing the props down to the child,
02:11 it's actually going to pass a React element to the child. So here I'm saying, child, here's your grandchild, and I'm rendering the grandchild component myself. And even with the grandchild component, now it accepts a button component. So I'm rendering the button component. And so both the child and the grandchild actually don't know anything about the count
02:29 or the update count or the increment methods. Those are all managed by the app. And these different components are just accepting the UI that they're responsible for laying out. And that's why I call these layout components, because the child is rendering some content and stuff,
02:47 and then it just says, when I've got a grandchild, this is where it goes. And the grandchild is saying, here's my content, and if I've got a button, this is where it's going to go. So they're laying things out in the UI, and that's their responsibility. And by doing things this way, you can have an app that's a server component, and then the child that's a client component, and then this grandchild could be the server components again,
03:08 or however, vice versa, you want to structure this. But the benefit here being that you can mix and match these different types of components in a really nice way. They compose together nicely. And then, of course, the benefit here being any changes to the UI
03:26 or to the way that the state is managed or anything like that can all be local to this. And these layout components can be left really simple. You don't have to worry about changing those. A real world example of this is in actually my own website. Pretty much like most of my pages have this header,
03:46 which has some text up here, some secondary text, and then some interesting thing here and an image right here. And so it doesn't always have some interesting thing here. Sometimes it has a button and an arrow. Other times it has like a search input. It's going to be just different per page. And so the header component is really just a thing
04:07 that's responsible for laying things out. And the one that's rendering the header is saying, here's what I want you to render. Like this one's got like an icon in here, whereas this does not. And so each one of these pages is still using the same reusable component
04:24 because it is nice to have these effects be shared and all of that stuff. But the stuff that's unique about each one of these is going to be controlled by in the place where it is unique. So I find that this pattern shows up pretty much everywhere that I'm writing React applications.
04:43 And that's why we're learning it in our workshop today. So why don't we get into it?