Transcript
00:00 Let's talk about one of the most popular patterns for components in the React ecosystem these days, and it is compound components. Here's the one-liner. The compound components pattern enables you to provide a set of components that implicitly share state for a simple yet powerful declarative API for reusable components.
00:19 What does that even mean? Let's actually look at HTML as our example for this. In HTML, we have a select and option tag, and each one of these by itself would do nothing, but together build a UI for that select that we're used to.
00:38 That is the idea of compound components. There is some state that is managed by the browser for us on which one of these options is currently selected, and from the DOM APIs, you can actually determine is this option selected, whatever. That state is managed by the browser for us,
00:53 but there's nothing in our HTML that says what that state is. We don't have to get that state and somehow provide the options or anything like that. It's all managed behind the scenes. If you were to build your own select thing, the naive way to do this would be to have
01:11 your custom select that takes an options property, and then it renders the select and renders the options, and that way it can manage all the state and things. But a more powerful way to do this is to just follow the pattern that HTML has with the select,
01:31 and have a component and then another component, and these two can communicate using context for which item is currently selected and what do we display. The big benefit here is that you have a much more discoverable API because you have all of these different options. You could say disabled,
01:51 so this option is disabled, or you're like, hey, we want to have a line between these in the UI. Whereas here, you'd have to say have some special break true or something like that, and that's just like some special API thing, where this is just like, oh, it's just another element.
02:09 Or maybe you want to have a div that surrounds all of this stuff for some styling reason. You can do that, and it's pretty natural to do so. The compound components pattern, much more declarative, easier to follow along, understand what the API is and everything. I'm grateful to Ryan Florence for creating this pattern.
02:28 Like I said, there's so many components out there that implement this pattern. Radix, most of their components implement this pattern. The way that they do it is they have you import all of the components on a namespace, and then they have you access those things on the namespace.
02:45 When I originally started teaching this years ago, I made the mistake of doing this and people thought that the compound components pattern was just having a namespace and you'd have a dot and then the component name. They thought that was the pattern. That's not the pattern. The pattern is the implicit state sharing
03:04 happening between the parent and the child components here. That is what makes this a really useful and helpful pattern. But yes, Radix implements this pattern in pretty much like most of their components,
03:22 their primitive components that they expose. And Radix is not alone. Many different libraries implement this pattern. And you're about to do so also.