Lesson 41 of 80
children is one slot. Passing JSX through named props gives you as many as you need — the trick behind every multi-region layout component.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
children is the slot React hands you for free — whatever sits between a component's opening and closing tags. But most real layouts have more than one region: a header, a sidebar, a footer, a toolbar. You don't need a special API for that. A prop can hold JSX just as easily as it can hold a string or a number, so you pass a whole chunk of markup through a prop named for what it represents, and the component drops it in the right spot.
This is often called the "slots" pattern, borrowed from web components terminology, even though React has no dedicated slot mechanism — it's just props, used deliberately.
function DashboardLayout({ header, sidebar, children }) {
return (
<div className="dashboard">
<header className="dashboard-header">{header}</header>
<div className="dashboard-body">
<aside className="dashboard-sidebar">{sidebar}</aside>
<main>{children}</main>
</div>
</div>
);
}
function ReportsPage() {
return (
<DashboardLayout
header={<TopNav user={currentUser} />}
sidebar={<ReportsFilterPanel />}
>
<ReportsTable />
</DashboardLayout>
);
}
header and sidebar are ordinary props — React doesn't treat them any differently than a title string prop. The only thing making them feel like "slots" is that DashboardLayout knows to render them in specific positions, and the caller supplies JSX instead of primitives. children fills the one remaining, unnamed region — the main content — because that's the slot every layout wants to be the ergonomic default for.
<Foo bar={<Baz />} /> works for the same reason <Foo bar={42} /> does: JSX expressions are just objects (React.createElement calls under the hood), and objects can be passed as props like anything else.children at all. A component can skip children entirely and take three or four named JSX props instead, if there's no single "obvious" default region. Don't force a layout into children + slots when it's really just three peer regions.sidebar doesn't guarantee a sidebar appears — the layout component can conditionally render it (e.g. hide it on a prop being undefined), which is exactly why this pattern composes so well for layouts with optional regions.This pattern doesn't need new machinery because props were never restricted to primitives — a prop is just a value passed at the call site, and JSX is a value like any other. The insight that "children is a prop too" is the same one this lesson builds on for named slots, just applied to the one prop every component gets implicitly instead of one you declare yourself.