HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptreactModeratepending

React Compound Component Pattern

Submitted by: @anonymous··
0
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.