The children Prop

Whatever sits between a component's opening and closing tags arrives as props.children. It is an ordinary prop with a reserved name: <Panel>hi</Panel> compiles to jsx(Panel, {children: 'hi'}), so <Panel children="hi" /> is identical. Its value is a string for one text child, an element for one element, and an array for several — never a predictable shape, which is why you render it rather than inspect it.

children gives a component a hole the caller fills: the pattern React 7,897 calls containment. For more than one hole, pass elements as extra props, as footer did in Function Components and Props. A layout built this way stays generic — it decides structure and spacing, the caller decides content.

A generic panel with one children slot and one named slotHTML
<div id="root" style="font:15px system-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script type="text/babel" data-type="module">
import React from 'https://esm.sh/react@19.3.0';
import { createRoot } from 'https://esm.sh/react-dom@19.3.0/client';
const box = { border: '1px solid #888', borderRadius: 6, padding: 10, width: 300 };
function Panel({ heading, actions, children }) {
  return (
    <section style={box}>
      <h3 style={{ margin: 0 }}>{heading}</h3>{children}
      <div style={{ borderTop: '1px solid #ddd' }}>{actions}</div>
    </section>
  );
}
createRoot(document.getElementById('root')).render(
  <Panel heading="Order 4821" actions={<><button>Ship</button> <button>Cancel</button></>}>
    <p>2 items, 1.4 kg</p><p>Ships from Kuala Lumpur</p>
  </Panel>
);
</script>
Browser output of Listing 2.11
Browser output of 11

Both paragraphs land in children as a two-element array, while the two buttons arrive in actions wrapped in a fragment, since a prop holds a single value. React matches children by position, so conditionally rendering one of them shifts the array and can reset state further down; give conditional children a key when that matters. Children.map, Children.toArray and cloneElement still exist but are discouraged — they force a parent to know its children's shape, and break as soon as a caller wraps a child in a fragment.