Lesson 2 of 12
Props & Composition
You will learn how to pass data from a parent component to a child with props, and how to nest components using children. Props are how components share data.
// Props are the function's first argument
function UserCard({ name, email, avatar, role = "user" }) {
return (
<div className="card">
<img src={avatar} alt={name} width={48} height={48} />
<div>
<strong>{name}</strong>
<span>{email}</span>
<span className={`badge badge-${role}`}>{role}</span>
</div>
</div>
)
}
// Using the component
function App() {
const user = {
name: "Alice",
email: "alice@example.com",
avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Alice",
role: "admin",
}
return <UserCard {...user} /> // spread object as props
}// children — the content between component tags
function Card({ title, children, footer }) {
return (
<div className="card">
{title && <h2 className="card-title">{title}</h2>}
<div className="card-body">{children}</div>
{footer && <div className="card-footer">{footer}</div>}
</div>
)
}
// Usage
function App() {
return (
<Card title="Welcome" footer={<button>Close</button>}>
<p>This is the card body.</p>
<p>children can be any valid JSX.</p>
</Card>
)
}
// Rendering lists — always provide a key
function TodoList({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id} className={item.done ? "done" : ""}>
{item.text}
</li>
))}
</ul>
)
}
// Conditional rendering
function Status({ isLoading, error, data }) {
if (isLoading) return <p>Loading...</p>
if (error) return <p className="error">{error.message}</p>
return <pre>{JSON.stringify(data, null, 2)}</pre>
}Finished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.