Composing Components
Building larger UIs by nesting components, and passing content through them with the children prop.
2 min read
Real React UIs are trees of small components nested inside larger ones. A page component renders a layout component, which renders a header and a list of card components, which each render a title and a button — composition, not inheritance, is how React shares and reuses UI.
function App() {
return (
<Page>
<Header title="Dashboard" />
<CardList items={items} />
</Page>
);
}The children prop
Every component automatically receives whatever is nested between its opening and closing tags as a special prop called children:
function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return (
<Card>
<h3>Title</h3>
<p>Some content inside the card.</p>
</Card>
);
}Card doesn't need to know anything about what's inside it — h3, p, or another component entirely. This is what makes components like layout wrappers, modals, and buttons reusable across completely different content: they own the structure (a bordered box, a centered overlay) and let the caller decide the content.
Composition over configuration
A common beginner instinct is to make a component's contents configurable through props instead:
// More rigid — Card has to know about every possible piece of content
function Card({ title, body }) {
return (
<div className="card">
<h3>{title}</h3>
<p>{body}</p>
</div>
);
}This works until you need a card with an image, or a button, or two paragraphs — then you're adding more props for each variation. Passing children instead keeps Card generic: it doesn't care what's inside, only how to wrap it.
Composing multiple slots
children covers the common "one blob of nested content" case, but a component can also accept multiple distinct pieces of JSX as ordinary named props, when it needs to place them in different spots:
function SplitPanel({ left, right }) {
return (
<div className="split">
<div className="left">{left}</div>
<div className="right">{right}</div>
</div>
);
}
<SplitPanel left={<Sidebar />} right={<MainContent />} />;Since JSX is just a value, there's nothing special about passing it as a regular prop — left and right here are just props that happen to hold JSX instead of a string or number.
The next lesson steps back to look at the broader process of designing a component tree from a UI mockup or requirement — a methodology commonly called "Thinking in React."