Composition

Build Big UIs by Nesting Small Components

Composition

Composition is React's superpower — pass JSX as children or slots to build flexible layouts without inheritance.

4 min read Level 2/5 #react#composition#patterns
What you'll learn
  • Compose components by nesting and passing JSX
  • Use slot props for multi-region layouts
  • Prefer composition over configuration

In React, composition means putting components inside other components. It’s how everything is built — there’s almost no use of inheritance, ever.

Build From Small Pieces

function Avatar({ src, alt }) {
  return <img className="avatar" src={src} alt={alt} />;
}

function NameTag({ name, role }) {
  return (
    <div>
      <strong>{name}</strong>
      <span className="role">{role}</span>
    </div>
  );
}

function UserCard({ user }) {
  return (
    <div className="card">
      <Avatar src={user.avatar} alt={user.name} />
      <NameTag name={user.name} role={user.role} />
    </div>
  );
}

Each piece is small, focused, and reusable on its own.

Containers That Take children

A container doesn’t need to know what goes inside it. Pass JSX as children:

function Panel({ title, children }) {
  return (
    <section className="panel">
      <h2>{title}</h2>
      <div className="panel__body">{children}</div>
    </section>
  );
}

<Panel title="Settings">
  <ThemeToggle />
  <LanguagePicker />
</Panel>

The Panel doesn’t care that its body has a toggle and a picker. It just renders whatever the caller passed.

Multi-Slot Layouts

When you need more than one “region”, use named props that take JSX:

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

<PageLayout
  header={<TopNav />}
  sidebar={<UserMenu />}
>
  <Article />
</PageLayout>

This is more flexible than a sea of boolean flags like <PageLayout showSidebar showNav />.

Composition Over Configuration

A component with 12 boolean props can usually be redesigned as a container that accepts children:

// ✗ Configuration soup
<Modal
  showClose
  showHeader
  title="Confirm"
  showCancel
  showOk
  okLabel="Yes"
  ...
/>

// ✓ Composition
<Modal>
  <Modal.Header>Confirm</Modal.Header>
  <Modal.Body>Are you sure?</Modal.Body>
  <Modal.Footer>
    <Cancel />
    <Ok label="Yes" />
  </Modal.Footer>
</Modal>

The composed version scales — adding a new piece doesn’t require a new prop.

No Inheritance

React doesn’t recommend extending components like in OOP. Instead, extract behavior into hooks (later) or wrap with another component.

Up Next

Real UIs show different things in different situations. Conditional rendering — the React way.

Conditional Rendering →