Skip to content
patterns questions

Patterns · 3 of 10senior~1 min

What is the Compound Components pattern?

#react#composition#api-design

Compound Components

The compound components pattern creates a group of components that work together and share implicit state. It gives the consumer flexible composition control.

Classic example - Select / Tabs

tsx
// usage - clean, expressive API <Tabs defaultValue="profile"> <Tabs.List> <Tabs.Trigger value="profile">Profile</Tabs.Trigger> <Tabs.Trigger value="settings">Settings</Tabs.Trigger> </Tabs.List> <Tabs.Panel value="profile"><ProfileForm /></Tabs.Panel> <Tabs.Panel value="settings"><SettingsForm /></Tabs.Panel> </Tabs>

Implementation with Context

tsx
interface TabsContext { active: string; setActive: (v: string) => void; } const TabsCtx = createContext<TabsContext | null>(null); const useTabs = () => useContext(TabsCtx)!; function Tabs({ defaultValue, children }: { defaultValue: string; children: React.ReactNode }) { const [active, setActive] = useState(defaultValue); return ( <TabsCtx.Provider value={{ active, setActive }}> <div>{children}</div> </TabsCtx.Provider> ); } function TabsList({ children }: { children: React.ReactNode }) { return <div role="tablist">{children}</div>; } function TabsTrigger({ value, children }: { value: string; children: React.ReactNode }) { const { active, setActive } = useTabs(); return ( <button role="tab" aria-selected={active === value} onClick={() => setActive(value)} > {children} </button> ); } function TabsPanel({ value, children }: { value: string; children: React.ReactNode }) { const { active } = useTabs(); return active === value ? <div role="tabpanel">{children}</div> : null; } // attach as static properties Tabs.List = TabsList; Tabs.Trigger = TabsTrigger; Tabs.Panel = TabsPanel;

Why it's better than prop drilling

tsx
// without compound components - prop soup <Tabs items={['Profile', 'Settings']} panels={[<ProfileForm />, <SettingsForm />]} defaultIndex={0} onTabClick={...} />

This pattern is used by Radix UI, Headless UI, Ark UI and shadcn/ui. Learning it is essential for building flexible design system components.

updated

did you know it?

related questions