patternjavascriptreactModeratepending
React Compound Component Pattern
Viewed 0 times
compound componentReact contextcompositiontabscomponent design
Problem
Complex components with many configuration props become unwieldy. Users need flexibility in composition without exposing implementation details.
Solution
Use compound components with React Context:
import { createContext, useContext, useState } from 'react';
// Context for shared state
const TabsContext = createContext(null);
// Parent component
function Tabs({ children, defaultTab }) {
const [active, setActive] = useState(defaultTab);
return (
<TabsContext.Provider value={{ active, setActive }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}
// Child components
function TabList({ children }) {
return <div role="tablist" className="tab-list">{children}</div>;
}
function Tab({ value, children }) {
const { active, setActive } = useContext(TabsContext);
return (
<button
role="tab"
aria-selected={active === value}
onClick={() => setActive(value)}
className={active === value ? 'active' : ''}
>
{children}
</button>
);
}
function TabPanel({ value, children }) {
const { active } = useContext(TabsContext);
if (active !== value) return null;
return <div role="tabpanel">{children}</div>;
}
// Attach sub-components
Tabs.List = TabList;
Tabs.Tab = Tab;
Tabs.Panel = TabPanel;
// Usage - clean, flexible API
<Tabs defaultTab="profile">
<Tabs.List>
<Tabs.Tab value="profile">Profile</Tabs.Tab>
<Tabs.Tab value="settings">Settings</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="profile"><ProfilePage /></Tabs.Panel>
<Tabs.Panel value="settings"><SettingsPage /></Tabs.Panel>
</Tabs>Why
Compound components keep related logic together while giving consumers full control over rendering and layout. Compare with a single <Tabs items={[...]} /> prop API which limits customization.
Gotchas
- Context must have a default value or null check for when components are used outside the parent
- Sub-components can be placed anywhere in the tree - they don't need to be direct children
Context
Designing reusable React component APIs
Revisions (0)
No revisions yet.