Skip to main content

# Compound Pattern

Create multiple components that work together to perform a single task

### Overview​

With the Compound Pattern, we can create multiple components that work together to perform one single task.

Let's say for example that we have a `Search` input component. When a user clicks on the search input, we show a `SearchPopup` component that shows some popular locations.

To create this behavior, we can create a `FlyOut` compound component.

This `FlyOut` component is an example of a compound component, as it also exposes some sub-components that all work together to toggle and render the `FlyOut` component.

The `FlyOut` compound component is a stateful component - which means we don't have to add the stateful logic to the `SearchInput` component.

### Implementation​

We can implement the Compound pattern using either a Provider, or `React.Children.map`.

#### Provider​

The `FlyOut` compound component consists of:

- `FlyoutContext` to keep track of the visbility state of `FlyOut`
- `Input` to toggle the `FlyOut`'s `List` component's visibility
- `List` to render the `FlyOut`'s `ListItems`s
- `ListItem` that gets rendered within the `List`.

Although we didn't have to name our compound component's sub-components `FlyOut.<ComponentName>`, it's an easy way to identify compound components, and only requires a single import.

#### `React.Children.map`​

Another way to implement the Compound pattern, is to use `React.Children.map` in combination with `React.cloneElement`. Instead of having to use the Context API like in the previous example, we now have access to these two values through `props`.

All children components are cloned, and passed the value of `open`, `toggle`, `value` and `setValue`.