Component Composition & the children Prop
Composition is how you build complex UIs out of small, generic pieces — by nesting them instead of bolting on more props. The key to it is the special children prop: whatever JSX you put between a component's tags is handed to that component as props.children . Master this and you'll write components that are reusable, readable, and never bloated with one-off configuration flags.
Learn Component Composition & the children Prop in our free React course — a beginner-friendly interactive lesson with runnable examples, a practice exercise…
Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
1️⃣ The children Prop
When you nest content inside a component, React collects it into props.children . The component then renders {' '} wherever it wants. This is the difference between a component that contains things and one that's hard-coded:
Notice Card has no idea what it's wrapping. The demo below models exactly that — a wrapper that frames whatever it's given:
2️⃣ Composition Beats Configuration
Imagine a Dialog built with props for every variation. It grows ugly fast:
The composed version never needs a new prop — the caller writes whatever markup they want. Your turn: complete a tiny Panel so it renders its title and then its children:
3️⃣ Named Slots
Sometimes one children isn't enough — you want distinct regions. Because props can hold any JSX , you simply add named props. Each one is a "slot":
The demo models a three-slot layout so you can see how each named region is filled independently:
4️⃣ Children as a Function (Render Props)
Here's the power move: children can be a function . The component calls it with data, and the caller decides how to render that data. This is the "render prop" pattern — composition for behavior, not just markup:
These lines of a reusable Modal wrapper are scrambled. Put them in the correct order:
1) You write . Where does the string "Hi" arrive inside Box?
As props.children . Box renders it wherever it places {' '} .
2) Your Card needs a header AND a footer region. One children isn't enough — what do you do?
Use named slots: accept JSX through props like header and footer , and render each where it belongs.
3) When does it make sense for children to be a function?
When the component owns some behavior or data (mouse position, list item, drag state) and wants the caller to decide how to render it — the render-props pattern.
📋 Quick Reference
Model an Alert that prefixes its children with an icon based on a type . Make "error" show "❌" and anything else show "ℹ️", then render the message after it.
Practice quiz
What is the children prop in React?
- A list of a component's child components only
- An array of the component's state
- Whatever JSX you nest between a component's opening and closing tags
- A reserved word that cannot be rendered
Answer: Whatever JSX you nest between a component's opening and closing tags. children is a special prop holding whatever you nest between the tags. The component renders it with {children}.
How does a generic wrapper component display the content passed into it?
- By rendering {children}
- By reading props.content
- By using document.body
- By calling this.render()
Answer: By rendering {children}. A wrapper renders the special children prop, e.g. <div>{children}</div>, so the caller controls the content.
What does 'composition over inheritance' mean in React?
- Extend a base component class to reuse behavior
- Always inline all components into one file
- Use only class components
- Build UIs by nesting/wrapping components instead of subclassing
Answer: Build UIs by nesting/wrapping components instead of subclassing. React shares behavior by composing — wrapping and nesting components — rather than class-style inheritance.
What is a 'slot' in React terms?
- A built-in <slot> element like Vue
- A named prop that accepts JSX for a distinct region (e.g. header, footer)
- A CSS grid area
- A special hook
Answer: A named prop that accepts JSX for a distinct region (e.g. header, footer). React has no formal slot syntax; you accept JSX through named props such as header or footer to fill regions.
Why does composition often beat adding more configuration props?
- The caller passes real JSX, so the component stays generic without a prop for every variation
- It makes components render faster
- It removes the need for state
- Props are not allowed in modern React
Answer: The caller passes real JSX, so the component stays generic without a prop for every variation. Instead of a prop per variation, you accept children/slots and let the caller supply markup — fewer props, more flexibility.
In the render-props pattern, children is...
- A string
- An array of elements
- A function the component calls with data
- Always null
Answer: A function the component calls with data. children can be a function; the component calls children(data) and the caller decides how to render that data.
You write <Box>Hi</Box>. Where does the string 'Hi' arrive inside Box?
- props.text
- props.children
- props.value
- props.slot
Answer: props.children. Nested content arrives as props.children, which Box renders wherever it places {children}.
What happens if a wrapper component forgets to render {children}?
- React throws an error
- The children render at the top of the page
- The component re-renders forever
- The nested content simply does not appear
Answer: The nested content simply does not appear. If you never render {children}, the component shows its own markup but the nested content vanishes.
Your Card needs both a header AND a footer region. What is the clean approach?
- Pass two separate children arrays
- Use named slot props like header and footer
- Use two nested Card components
- Store both in component state
Answer: Use named slot props like header and footer. One children isn't enough for distinct regions; accept named props (header, footer) and render each where it belongs.
Render props were largely the precursor to which modern feature for sharing logic?
- Portals
- Error boundaries
- Custom hooks
- Suspense
Answer: Custom hooks. Custom hooks now handle most logic sharing, though render props still fit when behavior must wrap markup.