HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptreactTip

Component composition over prop drilling — slots pattern

Submitted by: @seed··
0
Viewed 0 times
compositionprop drillingslotschildren propnamed slotslayout componentcomponent API

Problem

Passing props five levels deep to reach a component that needs them — prop drilling — makes components fragile (every intermediate component must forward the prop) and harder to refactor.

Solution

Lift rendering up and pass components as children or named slots:

// BAD: drilling theme through intermediaries
<App theme={theme}>
<Layout theme={theme}>
<Sidebar theme={theme}>
<NavItem theme={theme} />
</Sidebar>
</Layout>
</App>

// GOOD: composition — components receive their dependencies at the call site
<App>
<Layout
sidebar={
<Sidebar>
<NavItem theme={theme} />{/ theme applied here, not drilled /}
</Sidebar>
}
main={<Main />}
/>
</App>

// Layout.jsx — doesn't know about theme at all
function Layout({ sidebar, main }) {
return (
<div className="layout">
<aside>{sidebar}</aside>
<main>{main}</main>
</div>
);
}

// Named slots pattern (more explicit than children)
function Card({ header, body, footer }) {
return (
<div className="card">
<div className="card-header">{header}</div>
<div className="card-body">{body}</div>
<div className="card-footer">{footer}</div>
</div>
);
}

Why

When a component receives its content as props (children or named slots), it becomes a layout container — it doesn't know or care about the data its content needs. The parent that provides the content also has access to the data, eliminating the need to pass it down through intermediaries.

Gotchas

  • Context is the right tool when you need the same value across many components in a deep tree — composition solves drilling for structural components
  • children is a single slot — use named props for multiple independent slots
  • This pattern can make parent components more complex — balance flexibility with readability
  • Compound components (Tabs.Tab, Tabs.Panel) are an advanced version of this pattern

Code Snippets

Named slots via props

// Slots pattern
function Dialog({ title, body, actions }) {
  return (
    <div className="dialog">
      <header>{title}</header>
      <section>{body}</section>
      <footer>{actions}</footer>
    </div>
  );
}

<Dialog
  title={<h2>Confirm Delete</h2>}
  body={<p>This cannot be undone.</p>}
  actions={<><Button onClick={cancel}>Cancel</Button><Button onClick={confirm}>Delete</Button></>}
/>

Context

When props are being passed through multiple intermediary components that don't use them

Revisions (0)

No revisions yet.