Chapter 1 of 4

Composition First

The pattern that removes the need for most of the others.

Before reaching for a named pattern, remember that React's core idea already solves most reuse problems: components accept other components.

Slots

Give a component named holes for content and let callers fill them. It stays flexible without growing a wall of boolean props.

function PageLayout({ header, sidebar, children, footer }) {
  return (
    <div className="page">
      <header>{header}</header>
      <div className="body">
        <aside>{sidebar}</aside>
        <main>{children}</main>
      </div>
      <footer>{footer}</footer>
    </div>
  );
}

<PageLayout
  header={<SiteHeader />}
  sidebar={<Filters />}
  footer={<Legal />}
>
  <Results />
</PageLayout>

Specialisation by wrapping

A specific component is often just a general one with some props filled in. No inheritance required.

function Dialog({ tone = "neutral", title, children }) { /* ... */ }

function ConfirmDeleteDialog({ onConfirm, children }) {
  return (
    <Dialog tone="danger" title="Delete this item?">
      {children}
      <button onClick={onConfirm}>Delete</button>
    </Dialog>
  );
}