CodeOath
← All posts
React75 min total · 17 parts

React Fundamentals: Components, Hooks, and the Virtual DOM

Contents — Part 14 of 17: Component Composition Patterns
Part 14 of 17 · ~1 min

Component Composition Patterns

Children as composition

Already introduced above — the simplest and most common pattern. Instead of a component accepting a variant prop for every possible thing that could appear inside it, it accepts arbitrary children:

// Rigid — Modal has to anticipate every possible use case as a prop
<Modal title="Confirm" message="Are you sure?" showCancelButton confirmText="Delete" />

// Composable — Modal just provides structure; the caller controls the content
<Modal>
  <Modal.Header>Confirm</Modal.Header>
  <Modal.Body>Are you sure?</Modal.Body>
  <Modal.Footer><button>Cancel</button><button>Delete</button></Modal.Footer>
</Modal>

Compound components

The Modal.Header/Modal.Body pattern above is a compound component — several components designed to be used together under one parent's namespace, often sharing implicit state via Context so children don't need explicit props wired between them by the caller.

Render props (mostly superseded by hooks)

Before hooks existed, sharing stateful logic between components required either inheritance (rare in React) or the render props pattern — a component whose children (or another prop) is a function it calls with some state:

<MouseTracker>
  {({ x, y }) => <p>Mouse at {x}, {y}</p>}
</MouseTracker>

Custom hooks solve the same problem more directly today (const { x, y } = useMouseTracker();), which is why render props are much less common in new code — but the pattern still appears in some libraries and is worth recognizing.