Compound composition is a design pattern where multiple related components work together implicitly, sharing state via React Context. Component composition is the broader, fundamental principle of building UIs by nesting components, passing data explicitly via props.
In React, both compound composition and component composition are techniques for building reusable and flexible UIs, but they operate at different levels of complexity. Component composition is the foundational concept of React itself: building interfaces by nesting components and passing data from parent to child through props . Compound composition is a specific advanced pattern that builds on top of composition, creating a set of components that are designed to work together as a single, cohesive unit, often by sharing an implicit state via React Context .
Component composition is the core idea that UI elements are created by combining other components. It relies on the React prop model (children, props) and creates a clear, explicit data flow. This pattern is universal, simple, and used in almost every React application.
Compound composition is a design pattern where multiple components (the "compounds") are designed to work together as a single unit. They share an implicit state (often via Context) and communicate behind the scenes, allowing for a more declarative and flexible API. This pattern is ideal for building components like <select> and <option>, <Tab> and <TabPanel>, or <Accordion> and <AccordionItem> where child components need to communicate with a parent component without explicit prop drilling.
State Management: Component composition uses explicit props passed down; compound composition uses implicit shared state via Context or React.Children.map .
Complexity: Component composition is simpler and more direct; compound composition is more complex but provides a cleaner API for complex UI components.
Flexibility: Component composition gives parents full control over children via props; compound composition enforces a specific relationship between components.
Use Cases: Component composition is used everywhere (buttons, cards, lists); compound composition is used for complex UI widgets (tabs, accordions, select menus).
Data Flow: Component composition flows data from parent to child explicitly; compound composition allows child components to communicate with the parent implicitly.
You have a simple parent-child relationship (e.g., Card and CardContent).
You need explicit control over data flow.
You want to keep your component API simple and predictable.
You are building generic, reusable components (like Button, Input, Modal).
You are building complex widgets with multiple interacting parts (e.g., Select, Tabs, Accordion).
You want to provide a declarative API that hides internal state management from the consumer.
You need child components to communicate with a parent without prop drilling.
You are building a component library where components are designed to be used together as a suite (e.g., <Select>, <Option>, <OptionGroup>).