All topics
Patternsadvanced

Compound Components

Learn how compound components share implicit state between a parent and its children via context, giving a flexible, declarative API.

The compound components pattern lets a group of components work together to form a cohesive unit, similar to how HTML's <select> and <option> implicitly cooperate, while giving consumers flexibility in how they arrange and configure the children. A parent component (like Tabs) manages shared state internally and exposes it to its children (Tabs.List, Tabs.Panel) via Context, rather than requiring the consumer to manually wire props between siblings.

Compound components are like a table place setting: the plate, fork, and glass (sub-components) are separate physical pieces you can arrange as you like on the table, but they're all implicitly coordinated as part of 'one place setting' (the parent's shared context) rather than each being wired together by hand every time you set the table.

Key Concepts

1
This produces a very readable, declarative consuming API: <Tabs><Tabs.List>...</Tabs.List><Tabs.Panel>...</Tabs.Panel></Tabs> clearly expresses the relationship without the consumer needing to manage which tab is active or pass that state around manually — the compound component handles it internally and exposes only what's needed through context.
<Tabs><Tabs.List>...</Tabs.List><Tabs.Panel>...</Tabs.Panel></Tabs>
2
The pattern relies on attaching sub-components as static properties of the parent (Tabs.List = TabsList) purely as an organizational and namespacing convenience — the actual state-sharing mechanism underneath is Context, not the static property assignment itself. Children read the shared context value via a hook like useTabsContext(), typically with a guard that throws if used outside the parent.
Tabs.List = TabsListuseTabsContext()
3
Interviewers use compound components to assess whether a candidate can design a component API that's both flexible (consumers can rearrange, omit, or interleave children freely) and cohesive (the pieces share state correctly without prop drilling), and whether they understand Context is the actual state-sharing mechanism underneath the sugar of dot-notation sub-components.