React Component Composition with Props
Table of Contents
In the last lesson you learned about React Children Props, where a component wraps whatever you put between its tags. This lesson goes one step further: combining small components into bigger ones so you build one flexible piece instead of copying it everywhere.
๐งฉ What Is Component Composition?
Composition just means building bigger components out of smaller ones. Here is the idea broken down.
- It is the React way of reusing UI. You make small pieces, then snap them together like building blocks.
- You combine components two ways: by nesting them, and by passing data and other components in through props.
- A โparentโ component decides the overall shape. The pieces it gets filled in with come from outside.
- The goal is one flexible component that works in many situations, instead of many almost-identical copies.
Here is a tiny example. A Page component lays out the structure, and the actual content gets dropped inside it.
function Page() { return ( <div className="page"> <Header /> <Content /> <Footer /> </div> );}See what happened there?
Pageis composed ofHeader,Content, andFooter.- None of those pieces know about each other. They just sit together.
- That is composition in its simplest form.
๐ Composing With children + props Together
The most common pattern is mixing children with normal props. Here is why that combo is so useful.
- Use named props for the fixed slots, like a title or a footer. You decide where each one goes.
- Use
childrenfor the main body. Whatever the caller puts between the tags lands there. - Together they give you a component with a clear layout but flexible content.
Here is a Card that takes a title prop, a footer prop, and renders children in the middle.
function Card({ title, footer, children }) { return ( <div className="card"> <h2 className="card-title">{title}</h2> <div className="card-body">{children}</div> <div className="card-footer">{footer}</div> </div> );}
function App() { return ( <Card title="Welcome back, Alex" footer={<button>View profile</button>} > <p>You have 3 new messages waiting for you.</p> </Card> );}Walking through it:
titleis plain text, so it shows up in the heading.footeris actually a whole<button>element passed as a prop. React is happy to take JSX as a prop value.- The
<p>between the tags becomeschildrenand fills the body. - So one
Cardhandles all three slots. The sameCardcan be a message card today and a settings card tomorrow.
JSX is just a value
You can pass JSX anywhere you pass a normal value: as a prop, in an array, even from a function. That is the whole trick that makes composition work.
๐ฆ Passing Components As Props
Sometimes you want a component to take whole sections as props, not just text. Here is how that looks.
- A layout component can accept a
headerprop and asidebarprop, each holding a full component. - The layout decides the positions. The caller decides what goes in each position.
- This keeps the layout reusable. Different pages can drop in different headers and sidebars.
Here is a Page layout that takes header, sidebar, and content as props.
function Page({ header, sidebar, content }) { return ( <div className="page"> <header className="page-header">{header}</header> <div className="page-main"> <aside className="page-sidebar">{sidebar}</aside> <main className="page-content">{content}</main> </div> </div> );}
function Dashboard() { return ( <Page header={<SiteHeader />} sidebar={<NavMenu />} content={<ReportList />} /> );}Notice what Page does and does not know.
Pagenever knows what a header or a sidebar actually contains. It only knows where to place them.- Tomorrow you can build a
Settingspage with the samePageand just swap in different components. - So the layout stays. The contents change.
๐ฏ Specialization: From Generic To Specific
Now a really useful idea called specialization. Here is what it means.
- Specialization means you build one generic component, then make specific versions of it by passing fixed props.
- The generic one knows the general shape. The specific one fills in the details once, so callers donโt repeat them.
- This is how you avoid ten slightly different dialog components. You keep one and specialize it.
Here is a generic Dialog, and a WelcomeDialog that specializes it with fixed content.
function Dialog({ title, message, children }) { return ( <div className="dialog"> <h1 className="dialog-title">{title}</h1> <p className="dialog-message">{message}</p> {children} </div> );}
function WelcomeDialog() { return ( <Dialog title="Welcome" message="Thank you for joining us. We are glad you are here." > <button>Get started</button> </Dialog> );}What is happening:
Dialogis the generic piece. It just renders a title, a message, and whatever children you pass.WelcomeDialogis the special version. It handsDialoga fixed title and message, plus a button as children.- Anywhere you want that welcome popup, you just write
<WelcomeDialog />. The details live in one place. - So if you later want a
GoodbyeDialog, you write another small wrapper around the sameDialog. No copy-paste, no duplicated layout.
๐ซ Why Composition, Not Inheritance
If you come from another language, you might reach for inheritance to share behavior. In React, you donโt. Here is why.
- React has no good use case for inheritance between components. The team behind React recommends composition instead.
- Inheritance ties components together in a rigid chain. Change the base and you risk breaking everything below it.
- Composition keeps pieces independent. You combine them, but none of them depends on the inner workings of another.
- Anything you might do with inheritance, you can do more clearly by passing props and children.
Here is the contrast in code. One side tries to extend a base component, the other just composes.
// โ Avoid: trying to inherit UI from a base componentclass FancyButton extends Button { // React does not work like this for sharing UI render() { return super.render(); }}
// โ
Do this: compose by passing props and childrenfunction Button({ style, children }) { return <button className={style}>{children}</button>;}
function FancyButton({ children }) { return <Button style="fancy">{children}</Button>;}So FancyButton does not inherit from Button. It just uses Button and passes the right props. That is cleaner and easier to change later.
Coming from class-based languages?
The โextend a base class to share UIโ habit does not carry over to React. Reach for composition first. Build small components and combine them.
โ Best Practices
A few habits that keep composition clean. Here they are.
- Keep each component focused on one job. Small pieces compose better than big ones.
- Use
childrenfor the main content, and named props for the fixed slots like header or footer. - Build generic components first, then specialize them with wrapper components when you need a specific version.
- Reach for composition before any clever sharing trick. It is the pattern React is built around.
A simple rule
If you feel like copying a component just to change a little bit, stop. Make the original take a prop or children for that part, then compose instead. One flexible component beats five near-copies.
๐งฉ What Youโve Learned
- โ Composition means building bigger components by combining smaller ones
- โ
You can pass whole components as props, like a
headerorsidebar - โ
childrenplus named props together give you flexible, well-shaped components - โ Specialization turns one generic component into specific versions with fixed props
- โ React favors composition over inheritance for sharing and reusing UI
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does component composition mean in React?
Why: Composition is about combining small components into bigger ones, by nesting them and by passing data and components through props.
- 2
How can you pass a whole component as a prop?
Why: JSX is just a value, so you can pass a full element as a prop, for example header={<SiteHeader />}. The parent decides where to place it.
- 3
What is specialization in React?
Why: Specialization means a generic component (like Dialog) becomes a specific one (like WelcomeDialog) by passing fixed props and children.
- 4
Why does React favor composition over inheritance?
Why: Composition keeps components independent and flexible. React has no good use case for inheritance between components, so composition is the recommended pattern.
๐ Whatโs Next?
Now you can combine components into flexible UIs instead of copying layouts everywhere. Next, letโs tidy up how you actually pass data into them with some solid habits.