R
Interview Deckreact · next.js · senior/staff
0·0·122
Padrões

Compound Components

Componentes que cooperam via Context. <Tabs><Tab/><Panel/></Tabs> em vez de props gigantes.

Compound Components é um padrão onde múltiplos componentes trabalham juntos, compartilhando state implícito via Context. Em vez de uma API monolítica com muitas props, você compõe pequenos componentes que 'sabem' do pai.

Problema
APIs com muitas props (config: { tabs: [...], activeTab: 0, onChange: ... }) ficam rígidas e difíceis de customizar. Cada novo caso requer nova prop.
Solução
Pai cria Context. Filhos consomem. API se torna composicional: <Tabs><TabList><Tab/></TabList><TabPanel/></Tabs>. Flexível, intuitivo, fácil de extender.
Tip
Padrão usado por Radix UI, Headless UI, shadcn/ui. Combina super bem com 'Server Component pattern' onde a composição é feita no parent server-side.
const TabsContext = createContext(null);

function Tabs({ children, defaultValue }) {
  const [active, setActive] = useState(defaultValue);
  return (
    <TabsContext.Provider value={{ active, setActive }}>
      <div className="tabs">{children}</div>
    </TabsContext.Provider>
  );
}

function Tab({ value, children }) {
  const { active, setActive } = useContext(TabsContext);
  return (
    <button
      className={active === value ? 'active' : ''}
      onClick={() => setActive(value)}
    >
      {children}
    </button>
  );
}

function Panel({ value, children }) {
  const { active } = useContext(TabsContext);
  if (active !== value) return null;
  return <div>{children}</div>;
}

// Uso
<Tabs defaultValue="a">
  <Tab value="a">A</Tab>
  <Tab value="b">B</Tab>
  <Panel value="a">Conteúdo A</Panel>
  <Panel value="b">Conteúdo B</Panel>
</Tabs>
Q.Quais bibliotecas usam compound components?
A.Radix UI (Dialog, Tabs, etc), Headless UI, React Aria, Reach UI. shadcn/ui (que usa Radix por baixo). React Hook Form. É o padrão moderno de design de componentes.
Q.Como compartilhar state entre compound components?
A.Context API. O pai (<Tabs>) cria o context com state. Os filhos (<Tab>, <TabPanel>) consomem via useContext. State 'flui' implicitamente sem props drilling.
Q.Vantagem sobre props config?
A.1) Mais flexível (qualquer ordem/aninhamento). 2) Menos verboso para casos simples. 3) Fácil de extender (adicionar novos sub-componentes não quebra API). 4) Melhor IntelliSense.
44/122← →