Understanding Props and Children
React is built on composition — assembling small, reusable pieces into larger UIs. But composition only works if each piece can receive data from the outside world.
- •What props are and how they work
- •How to pass props to components
- •Different types of props (strings, numbers, objects, functions, JSX)
- •What props.children is and how to use it
- •Practical examples of component composition
You already know this pattern from plain JavaScript.
Functions accept inputs, operate on them, and return something useful.
function formatPrice(amount) {
return `$${amount.toFixed(2)}`
}
function calculateTotal(price, taxRate) {
return price + price * taxRate
}
function getReceipt(amount, taxRate) {
return {
subtotal: formatPrice(amount),
total: formatPrice(calculateTotal(amount, taxRate))
}
}
getReceipt(20, 0.07)Each function depends on the ability to receive arguments.
Without that, the whole chain breaks.
React works exactly the same way.
What Are Props?
Props are the way components receive data.
They're the React equivalent of function arguments.
If you understand arguments, you already understand props.
Passing Props to Components
Passing a prop to a component looks just like setting an attribute on an HTML element:
<Greeting name="Lena" />You're simply giving the component some information to work with.
Props Can Be Anything — Not Just Strings
You can pass booleans, numbers, arrays, functions, JSX, or objects:
<Dashboard
user={{ id: 42, name: "Lena" }}
theme="dark"
notifications={12}
onLogout={handleLogout}
header={<HeaderIcon />}
/>Why the Curly Braces?
Anything not a string must go inside {} because JSX needs a way to interpret JavaScript expressions.
Objects use {{ }}:
<Chart options={{
showGrid: false,
type: "bar",
colors: ["#ff4d4d", "#4d79ff"]
}} />One pair is for JSX, one pair is the object literal.
Boolean Shorthand
These two are identical:
<Notification muted={true} />
<Notification muted />If you skip the value, React sets the prop to true.
Accessing Props Inside a Component
React places all props into a single props object, which is passed as the first argument to your component function.
function Greeting(props) {
return <h2>Hello, {props.name}!</h2>
}You can also destructure:
function Greeting({ name, emoji }) {
return <h2>Hello, {name} {emoji}</h2>
}Introducing props.children
So far, we've passed data using attributes.
But HTML has another way of providing content:
Whatever you place between opening and closing tags.
<button>Click me</button>React components can receive this content too:
<Banner>Welcome to the event!</Banner>
<Card>
<h3>Profile</h3>
<p>Some details here...</p>
</Card>Inside the component, that content is available as props.children.
Example: Banner Component
function Banner({ children }) {
return <div className="banner">{children}</div>
}Example: Page Layout Component
function PageLayout({ children }) {
return (
<section className="page">
<Navbar />
<div className="content">{children}</div>
<Footer />
</section>
)
}This pattern makes it easy to create reusable "wrapping" components that control layout, styling, or behavior while leaving the content flexible.
A Real-World Example: Reusable Modal
App.jsx
import React from "react"
import Modal from "./Modal"
export default function App() {
const [open, setOpen] = React.useState(false)
return (
<main>
<button onClick={() => setOpen(true)}>Show Modal</button>
{open && (
<Modal onClose={() => setOpen(false)}>
<h2>Custom Modal Content</h2>
<p>This text is passed through props.children.</p>
<small>You can change it each time.</small>
</Modal>
)}
</main>
)
}Modal.jsx
export default function Modal({ onClose, children }) {
return (
<div className="modal">
<button onClick={onClose}>Close</button>
<div className="modal-body">
{children}
</div>
</div>
)
}The Modal encapsulates:
- •structure
- •behavior
- •styling
…but the content is always different. That's the power of children.
Summary
React provides two powerful ways to pass content into components:
- •Passed as attributes
- •Work like function arguments
- •Can hold any type of data
- •Passed between opening and closing tags
- •Perfect for layouts, wrappers, modals, cards, tooltips, etc.
Together, they form the backbone of React's composable architecture.