React Children Props
Table of Contents + −
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, aModal, or a pageLayout. 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 ofCard. - 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 intoprops.childrenfor theCardcomponent 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> );}Carddoes not care what is inside it. It only draws the box and dropsprops.childrenin the middle.- In
App, everything between<Card>and</Card>becomes thatchildren. - So the
<h2>and the<p>both land inside the styleddiv.
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 thechildrenprop 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
Cardgets plain text as its children. - The second
Cardgets an<h2>, a<p>, and a<Button />component all together. - Same
Cardcomponent 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 renderfunction App() { return <Card />; // Card has nothing inside it. The page shows an empty box.}
// ✅ Right: content sits between the tags, so it becomes childrenfunction 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 }), notprops.childreneverywhere. - 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
- ✅
childrenis 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 }. - ✅
childrencan be text, HTML elements, or other components. - ✅ Wrapper components like
Card,Modal, andLayoutusechildrento 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
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
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
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
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.