React: From Components to Production · Components and JSX
Composition and children
Compose UIs with children, slots and render props instead of inheritance.
React favors composition: components accept children or named element props ("slots") and wrap them. This avoids prop drilling of display options and makes components flexible — e.g., a Card with header and children, or a Modal that renders any content. Render props (render={(item) => ...}) let parents customize rendering of internal data.
import type { ReactNode } from "react";
type CardProps = { title: ReactNode; actions?: ReactNode; children: ReactNode };
export function Card({ title, actions, children }: CardProps) {
return (
<section className="card">
<header className="card-header">
<h2>{title}</h2>
{actions}
</header>
<div className="card-body">{children}</div>
</section>
);
}
<Card title="Orders" actions={<Button variant="secondary">Export</Button>}>
<OrdersTable />
</Card>
export function Card({ title, actions, children }) {
return (
<section className="card">
<header className="card-header">
<h2>{title}</h2>
{actions}
</header>
<div className="card-body">{children}</div>
</section>
);
}
<Card title="Orders" actions={<Button variant="secondary">Export</Button>}>
<OrdersTable />
</Card>
Common pitfalls
- Boolean prop explosions (
showHeader,showFooter,compact…) instead of composition. - Trying to inherit from components (React doesn't use class inheritance for reuse).
- Passing components through many layers instead of composing at the top.
Key points
- Prefer composition over configuration
- children and named slots
- Composition reduces prop drilling
Further reading: react.dev: Passing JSX as children
Practice questions
How can composition reduce prop drilling?
Answer
Instead of passing data through intermediate components so a deep child can render it, the top-level component renders the child directly and passes it down as children or a slot prop.
What's a 'slot' prop?
Answer
A prop typed as ReactNode (like header or actions) that lets callers inject arbitrary elements into a specific place in the component's layout.
Open in the app to mark lessons complete, take notes and track your progress.