Lesson 16 of 31
Composition and Children
Building flexible components by passing other components in as children or props, rather than by trying to configure one giant component with an ever-growing list of options.
You've already used children to build a generic Card wrapper. This
lesson goes further: composition — building bigger components out of
smaller, independent ones combined by the caller — is one of React's most
important organizing ideas, and the alternative it avoids is worth seeing
directly.
The problem composition avoids
Imagine a Panel component that started simple and grew a prop for every
new variation someone needed:
function Panel({ title, showIcon, iconType, showFooter, footerText, showCloseButton }) {
return (
<div className="panel">
<div className="panel-header">
{showIcon && <Icon type={iconType} />}
<h3>{title}</h3>
{showCloseButton && <button>×</button>}
</div>
<div className="panel-body">{/* ...where does actual content go? */}</div>
{showFooter && <div className="panel-footer">{footerText}</div>}
</div>
);
}Every new use case adds another boolean and another prop, and Panel
itself has to understand and branch on all of them, forever. This scales
badly — the component becomes a small configuration language nobody enjoys
reading.
The composition-based alternative
Instead, let Panel accept arbitrary content and only handle the structural
parts it actually owns:
function Panel({ title, children }) {
return (
<div className="panel">
<div className="panel-header"><h3>{title}</h3></div>
<div className="panel-body">{children}</div>
</div>
);
}Every caller composes whatever it needs by nesting content inside Panel,
rather than describing it through props Panel has to know about in
advance:
<Panel title="Settings">
<SearchIcon />
<SettingsForm />
<button>Save</button>
</Panel>Panel never needs to change again just because a new caller wants a
slightly different combination of contents — it just renders whatever it's
handed.
Multiple "slots" with named props
children is one generic slot. Sometimes a component genuinely has more
than one distinct customizable area — an icon here, a footer there — and
passing a whole element as a specifically-named prop covers that:
function PageLayout({ icon, children, footer }) {
return (
<div className="layout">
<header>{icon}</header>
<main>{children}</main>
<footer>{footer}</footer>
</div>
);
}
<PageLayout
icon={<SearchIcon />}
footer={<p>© 2026 AniUI Academy</p>}
>
<SettingsForm />
</PageLayout>This is still composition, not configuration — PageLayout never inspects
what icon or footer actually contain, it just places them. Compare that
to a showIcon/iconType pair of props, where Panel itself would have
had to know how to construct and render every possible icon.
Composition also solves the "wrapper hides children's state" problem
A subtler benefit: passing components in as children (rather than a
parent trying to render them internally) means a re-render of the parent
doesn't necessarily need to re-render — or discard the state of — whatever
was passed in as children, since that JSX was created by the caller, not
recreated fresh by the parent's own render. This becomes relevant once
you're optimizing re-renders, later in this course; for now, the practical
takeaway is simpler: prefer composing components together over growing one
component's configuration surface indefinitely.
Try it yourself
What to remember
- Prefer letting a component accept content via
children(or a few named element props) over adding a new configuration prop for every new use case. - A prop can hold an entire React element, not just primitive values — useful when a component has several distinct customizable areas.
- Composition keeps components generic and reusable; configuration-heavy components tend to grow an unmaintainable list of flags over time.
Check yourself
3 questions · pass 3/3 to unlock Context and useContext
1.A Panel component grows a new boolean prop every time someone needs slightly different content inside it — showHeader, showFooter, showIcon, and so on. What's the composition-based alternative?
2.What does it mean to pass a component as a prop, rather than only ever using children?
3.Why is composition generally preferred over one large, heavily-configured component in React?
3 left to answer