
Prop Drilling vs Composition
Prop drilling is threading props through intermediate components that don’t use them. Composition solves many drilling problems before you need to reach for context.
The Drilling Problem
function App() {
const [user, setUser] = useState(currentUser);
return <Page user={user} onUserChange={setUser} />;
}
function Page({ user, onUserChange }) {
// Page doesn't use user — it just passes it through
return <Sidebar user={user} onUserChange={onUserChange} />;
}
function Sidebar({ user, onUserChange }) {
// Sidebar doesn't use it either
return <UserMenu user={user} onUserChange={onUserChange} />;
}
function UserMenu({ user, onUserChange }) {
return <button onClick={() => onUserChange(null)}>{user.name}</button>;
} Page and Sidebar are polluted with props they don’t own.
Fix: Component Composition
Pass the component with data already applied:
function App() {
const [user, setUser] = useState(currentUser);
const userMenu = <UserMenu user={user} onUserChange={setUser} />;
return <Page sidebar={<Sidebar menu={userMenu} />} />;
}
function Page({ sidebar }) {
return <div>{sidebar}</div>; // no user props needed
}
function Sidebar({ menu }) {
return <nav>{menu}</nav>; // same
} Page and Sidebar no longer know about users. The data flows directly to the leaf that needs it.
Children Prop
function Layout({ children, sidebar }) {
return (
<div className="layout">
<aside>{sidebar}</aside>
<main>{children}</main>
</div>
);
}
<Layout sidebar={<UserMenu user={user} />}>
<DashboardContent />
</Layout> When to Use Context
Context is appropriate when:
- Multiple unrelated components at different nesting levels need the same value
- Composition would require inverting too much of the component hierarchy
- The value changes infrequently (theme, locale, auth state)
When Composition Is Better
Composition wins when:
- The “drilled” data flows to a single leaf component
- You can restructure the component hierarchy without major churn
- You want to avoid context’s re-render behavior
Rule of Thumb
Try composition first. If it requires too much restructuring, or if multiple distant leaves need the same value, reach for context.









