React Props Children

The special children prop lets a component render whatever JSX was placed between its opening and closing tags, which is the foundation of composable React design.

What Is props.children?

Whenever you nest JSX inside a component's tags, React automatically collects that nested content and passes it to the component as props.children. You never declare children explicitly in JSX attributes — it's implicit, derived purely from what you put between the opening and closing tags.

Rendering children Directly

function Card({ children }) {
  return <div className="card">{children}</div>;
}

function App() {
  return (
    <Card>
      <h2>Plan: Pro</h2>
      <p>Includes unlimited projects.</p>
    </Card>
  );
}

export default App;

Why Children Enable Composition

Composition means building complex UI by combining smaller components, rather than configuring one giant component with dozens of props. A Card component that renders {children} doesn't need to know whether it contains a paragraph, a form, or another component — it just provides a wrapper (styling, layout, a border) and lets the caller decide the content. This is the same idea as HTML's <div> or <ul>, which don't care what's inside them.

children Can Be Anything Renderable

props.children isn't limited to a single element. It can be a string, a number, an array of elements, another component, or nothing at all (undefined) if the component was self-closed. React.Children utilities like React.Children.map and React.Children.count exist specifically to safely iterate over children regardless of shape.

  • Single element: <Card><p>Text</p></Card>
  • Multiple siblings: <Card><h2>Title</h2><p>Body</p></Card>
  • Plain text: <Card>Just a string</Card>
  • Nothing: <Card /> renders children as undefined
  • A function (render props pattern): <Card>{(data) => <p>{data}</p>}</Card>

A Layout Component with Named Slots and Children

function Panel({ title, children }) {
  return (
    <section className="panel">
      <header className="panel-title">{title}</header>
      <div className="panel-body">{children}</div>
    </section>
  );
}

function Dashboard() {
  return (
    <Panel title="Recent Activity">
      <ul>
        <li>Signed in from a new device</li>
        <li>Password changed</li>
      </ul>
    </Panel>
  );
}

export default Dashboard;
Note: This pattern — a named prop like 'title' combined with children for the main slot — is how libraries like Material UI and Chakra structure most of their layout components.

Conditionally Wrapping Children

Because children is just a prop, you can inspect it, transform it, or conditionally render it like any other value. A common pattern is showing a fallback when no children were passed.

Fallback Content When Empty

import React from 'react';

function EmptyableList({ children }) {
  const hasContent = React.Children.count(children) > 0;
  return (
    <div>
      {hasContent ? children : <p>Nothing here yet.</p>}
    </div>
  );
}

export default function App() {
  return (
    <div>
      <EmptyableList>
        <p>First item</p>
      </EmptyableList>
      <EmptyableList />
    </div>
  );
}
Note: Cloning and injecting extra props into children with React.cloneElement works, but it silently couples the parent to the exact shape of its children. Prefer explicit props or context when the relationship needs to be more than 'just render me'.
PatternWhen to Use It
Plain childrenGeneric wrappers: Card, Panel, Modal, Layout
Named prop + childrenOne fixed slot (title, header) plus a flexible body
Multiple named props (no children)Several fixed, non-interchangeable slots
Function as children (render props)Child needs data or behavior from the parent

Exercise: React Props Children

What does `props.children` refer to inside a component?