React Children Props

In the last lesson you learned React Default Props, where a component falls back to a safe value when no prop is passed. This lesson is about the special children prop, which lets one shell like a Card wrap whatever content you drop inside it.

🤔 Why do we need children?

So far you passed data into a component as named props like name or price. But sometimes what you want to pass is not a value. It is a whole chunk of UI.

  • Think of a Card, a Modal, or a page Layout. The outer shell stays the same. Only the content inside changes.
  • Passing that content as a normal prop gets ugly fast. You’d be stuffing JSX into a string-like attribute.
  • React gives you a cleaner way. Whatever you write between the opening and closing tags is handed to the component as props.children.

The key idea

children is just a prop, like any other. The only special thing is HOW you pass it. Instead of writing it as an attribute, you put it between the component’s tags.

🧩 What is the children prop?

The children prop is the content you place between a component’s opening and closing tags. React collects it and gives it to you automatically as props.children.

Here is the smallest example. Look at what sits between <Card> and </Card>.

function App() {
return (
<Card>
<h2>Hello there!</h2>
</Card>
);
}
  • The <h2>Hello there!</h2> is the children of Card.
  • You did not pass it as an attribute. You just wrote it inside the tags, like normal HTML.
  • React takes that <h2> and puts it into props.children for the Card component to use.

Think of it like a gift box. The box is always the same shape, but you can put anything inside it. The Card is the box, and the children is whatever you drop in.

💡 Rendering children inside a component

To actually show the content, the component reads props.children and puts it where it wants. Here the Card wraps its children in a styled div.

function Card(props) {
return <div className="card">{props.children}</div>;
}
function App() {
return (
<Card>
<h2>Welcome to Netflix</h2>
<p>Thousands of shows, one place.</p>
</Card>
);
}
  • Card does not care what is inside it. It only draws the box and drops props.children in the middle.
  • In App, everything between <Card> and </Card> becomes that children.
  • So the <h2> and the <p> both land inside the styled div.

What renders on the page

<div class="card">
<h2>Welcome to Netflix</h2>
<p>Thousands of shows, one place.</p>
</div>

The big win is reuse. The same Card can wrap a movie poster today and a login form tomorrow, and the shell never changes.

✂️ Destructuring children

Writing props.children everywhere gets repetitive. The common style is to destructure children straight out of props, so you can just write children.

function Card({ children }) {
return <div className="card">{children}</div>;
}
  • { children } pulls the children prop out of the props object for you.
  • Now you write {children} instead of {props.children}. Same thing, cleaner.
  • You can destructure other props alongside it too, like { title, children }.

This is the modern style

In real React code you’ll almost always see function Card({ children }). Destructuring children is the normal, expected way to write it.

🎁 Children can be anything

Here is the nice part. The children prop is not limited to one kind of thing.

  • It can be plain text, like <Card>Hello</Card>.
  • It can be HTML elements, like an <h2> and a <p>.
  • It can even be other components, like a <Button /> inside the card.

Here the same Card happily wraps text in one place and a full mix of elements and a component in another.

function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return (
<div>
<Card>Just a simple line of text.</Card>
<Card>
<h2>Your Order</h2>
<p>2 items in your cart.</p>
<Button label="Checkout" />
</Card>
</div>
);
}
  • The first Card gets plain text as its children.
  • The second Card gets an <h2>, a <p>, and a <Button /> component all together.
  • Same Card component both times. You never touched its code. You only changed what you put inside.

⚠️ Self-closing vs using children

A common mistake is writing the wrapper as a self-closing tag. If you do that, there is nothing between the tags, so children is empty and your content disappears.

// ❌ Wrong: self-closing, so there are no children to render
function App() {
return <Card />; // Card has nothing inside it. The page shows an empty box.
}
// ✅ Right: content sits between the tags, so it becomes children
function App() {
return (
<Card>
<h2>This text shows up</h2>
</Card>
);
}
  • A self-closing <Card /> sends no children. The styled box renders, but it is blank.
  • To pass children you need both an opening and a closing tag with content in between.
  • So remember: if a component is meant to wrap things, give it real open and close tags.

Empty box, not an error

A self-closing wrapper does not crash. It just renders empty. That makes the bug easy to miss, so check your tags first when a wrapper shows up blank.

🌍 Where children shines

Any component whose job is to wrap other content is a perfect fit for children. You’ll reach for this pattern constantly.

  • A Card that gives any content a border and shadow.
  • A Modal or popup that puts whatever you pass it inside a centered overlay.
  • A Layout that adds the header and footer around your page content.
  • A Button that styles itself but shows whatever label or icon you pass inside.

The idea is the same every time: the component owns the look of the shell, and you own the content.

✅ Best Practices

A few simple habits keep children-based components clean and predictable.

  • Destructure it: write function Card({ children }), not props.children everywhere.
  • Name wrapper components by their shell, like Card, Modal, Layout. The name should say what it wraps things in.
  • Always render {children} somewhere inside, or the content you pass will never show.
  • Use real opening and closing tags for wrappers. Skip the self-closing form when you want content inside.

🧩 What You’ve Learned

  • children is a special prop holding whatever you put between a component’s opening and closing tags.
  • ✅ You render it with {props.children}, or cleaner, by destructuring { children }.
  • children can be text, HTML elements, or other components.
  • ✅ Wrapper components like Card, Modal, and Layout use children to wrap any content.
  • ✅ A self-closing component passes no children, so the wrapper renders empty.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does the special children prop contain?

    Why: children holds the content placed between the opening and closing tags of a component, like <Card>...here...</Card>.

  2. 2

    Which is the modern way to read children inside a component?

    Why: Destructuring { children } out of props is the standard modern style. Then you render it with {children}.

  3. 3

    Which of these can be passed as children?

    Why: children is flexible. It can be plain text, HTML elements, other components, or a mix of all of them.

  4. 4

    Why does <Card /> show an empty box instead of your content?

    Why: A self-closing <Card /> has no content between an opening and closing tag, so children is empty and only the shell renders.

🚀 What’s Next?

Now you know how to wrap any content with children. Next we’ll combine that idea with regular props to build flexible components that mix a fixed shell with custom content.

React Component Composition with Props

Share & Connect