Composition Over Configuration
Instead of building one component with dozens of props to handle every possible variation, React favors composing smaller components together — nesting them the way you’d nest HTML elements.
A Reusable Layout Component
function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return (
<Card>
<h2>Card Title</h2>
<p>Any content can go here.</p>
</Card>
);
}Multiple "Slots" with Named Props
When a component needs more than one distinct content area, pass JSX through regular props (not just children) to create multiple "slots."
Multiple Content Slots
function SplitPanel({ left, right }) {
return (
<div style={{ display: "flex" }}>
<div className="left">{left}</div>
<div className="right">{right}</div>
</div>
);
}
function App() {
return (
<SplitPanel
left={<Sidebar />}
right={<MainContent />}
/>
);
}Avoiding "Prop Drilling"
Composition also helps avoid prop drilling — passing a prop through several intermediate components that don’t use it themselves, just to reach a deeply nested child. Passing already-rendered JSX as children skips the layers that don’t need the data at all.
Composition Avoids an Unnecessary Prop Chain
// Instead of threading 'user' through Layout and Sidebar just to reach Profile:
function Layout({ children }) {
return <div className="layout">{children}</div>;
}
function App({ user }) {
return (
<Layout>
<Profile user={user} />
</Layout>
);
}
// Layout never needs to know about 'user' at allBuilding Specialized Components from Generic Ones
A generic, flexible component can be wrapped to create a more specialized version with sensible defaults, without duplicating its implementation.
Best Practice
When you notice a prop being passed through several components that never use it themselves, look for a way to restructure with composition (children or named JSX slots) before reaching for Context — composition often solves the problem more simply.