React Tutorial 0/120 lessons ~6 min read Lesson 21

    Component Composition

    Component composition in React: build complex UI by combining small focused components with children, layouts, slots, and meaningful boundaries.

    Course progress0%
    Focus
    31 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Component Composition

    Component Composition is one of the most important ideas in React.

    Build complex UI by combining small, focused components instead of creating one large component.

    This is closely related to the previous lesson on Component Reusability. Reusability answers "Can I use this component again?" Composition answers "How can I combine components to build something larger?"

    1. What Is Component Composition?

    Imagine building an e-commerce product page.

    Instead of putting everything inside one component:

    tsx
    function ProductPage() {
    // 500 lines of code...
    }

    you can compose smaller components:

    text
    ProductPage
    │
    ├── Navbar
    ├── ProductGallery
    ├── ProductInfo
    │ ├── ProductTitle
    │ ├── Price
    │ ├── Rating
    │ └── Button
    ├── Reviews
    └── Footer
    tsx
    function ProductPage() {
    return (
    <>
    <Navbar />
    <ProductGallery />
    <ProductInfo />
    <Reviews />
    <Footer />
    </>
    );
    }

    That's component composition.

    2. Why Composition Matters

    Composition helps you create:

    • Smaller components
    • Easier-to-understand code
    • Reusable UI
    • Flexible layouts
    • Easier testing
    • Easier maintenance
    • Better separation of responsibilities

    Instead of one component knowing everything, each component focuses on its own job.

    3. The Basic Composition Pattern

    tsx
    function Header() {
    return <header>My Website</header>;
    }
    function Content() {
    return <main>Welcome!</main>;
    }
    function Footer() {
    return <footer>Copyright 2026</footer>;
    }
    function App() {
    return (
    <>
    <Header />
    <Content />
    <Footer />
    </>
    );
    }
    text
    App
    ├── Header
    ├── Content
    └── Footer

    App doesn't need to know how Header, Content, or Footer work internally.

    4. Composition with children

    One of the most important React composition patterns is the special children prop.

    tsx
    function Card({ children }: { children: React.ReactNode }) {
    return <div className="card">{children}</div>;
    }
    tsx
    <Card>
    <h2>Hello</h2>
    <p>Welcome to React.</p>
    </Card>

    React passes the content between the opening and closing tags as children.

    tsx
    // Conceptually:
    children = <h2>Hello</h2>

    5. Why children Is Powerful

    tsx
    function Container({ children }: { children: React.ReactNode }) {
    return <div className="container">{children}</div>;
    }

    You can reuse it with completely different content:

    tsx
    <Container>
    <h1>Home</h1>
    <p>Welcome to our website.</p>
    </Container>
    <Container>
    <ProductList />
    </Container>
    <Container>
    <LoginForm />
    </Container>

    The Container doesn't need to know what it's containing. That's excellent composition.

    6. Composition vs Props

    These two approaches are related but different.

    Props

    Pass data:

    tsx
    <ProductCard name="Banarasi Silk" price={4999} />

    children

    Pass nested content:

    tsx
    <Card>
    <ProductCard />
    </Card>
    text
    Props
    ↓
    "What information does this component need?"
    children
    ↓
    "What content should this component contain?"

    7. Example: Card Composition

    tsx
    function Card({ children }: { children: React.ReactNode }) {
    return <article className="card">{children}</article>;
    }
    tsx
    <Card>
    <h2>Product</h2>
    <p>Premium Banarasi Silk Saree</p>
    </Card>
    <Card>
    <h2>User Profile</h2>
    <p>Welcome, Rahul!</p>
    </Card>
    <Card>
    <h2>Order Summary</h2>
    <p>Total: INR 5,999</p>
    </Card>

    Same Card. Different composition.

    8. Component Composition Example

    tsx
    function ProductTitle({ name }: { name: string }) {
    return <h1>{name}</h1>;
    }
    function ProductPrice({ price }: { price: number }) {
    return <p>INR {price}</p>;
    }
    function BuyButton({ onBuy }: { onBuy: () => void }) {
    return <button onClick={onBuy}>Buy Now</button>;
    }
    function ProductInfo() {
    return (
    <section>
    <ProductTitle name="Banarasi Silk Saree" />
    <ProductPrice price={4999} />
    <BuyButton onBuy={() => alert("Purchased!")} />
    </section>
    );
    }
    function ProductPage() {
    return (
    <>
    <Navbar />
    <ProductGallery />
    <ProductInfo />
    <Reviews />
    <Footer />
    </>
    );
    }

    This is a component hierarchy.

    9. Composition Creates a Component Tree

    React applications can be visualized as a tree:

    text
    App
    │
    ├── Navbar
    │
    ├── ProductPage
    │ ├── ProductGallery
    │ ├── ProductInfo
    │ │ ├── ProductTitle
    │ │ ├── ProductPrice
    │ │ └── BuyButton
    │ └── Reviews
    │
    └── Footer

    Each component can compose other components. This is fundamental to how React apps are structured.

    10. Composition with Multiple Components

    You don't have to use only children.

    tsx
    function Modal({
    header,
    body,
    footer,
    }: {
    header: React.ReactNode;
    body: React.ReactNode;
    footer: React.ReactNode;
    }) {
    return (
    <div className="modal">
    <header>{header}</header>
    <main>{body}</main>
    <footer>{footer}</footer>
    </div>
    );
    }
    tsx
    <Modal
    header={<h2>Delete Account</h2>}
    body={<p>Are you sure?</p>}
    footer={<button>Delete</button>}
    />

    This is also composition.

    11. Named Composition Slots

    The previous example creates named areas:

    text
    Modal
    │
    ├── header
    ├── body
    └── footer
    tsx
    <Modal
    header={<ModalHeader />}
    body={<DeleteConfirmation />}
    footer={<ModalActions />}
    />

    This is useful for complex reusable components.

    12. Composition with children (Flexible Modal)

    tsx
    function Modal({ children }: { children: React.ReactNode }) {
    return <div className="modal">{children}</div>;
    }
    <Modal>
    <ModalHeader />
    <DeleteConfirmation />
    <ModalActions />
    </Modal>

    This can be even more flexible.

    13. Composition and Separation of Concerns

    Suppose we have one oversized component:

    tsx
    function UserProfile() {
    return (
    <div>
    {/* avatar */}
    {/* username */}
    {/* bio */}
    {/* followers */}
    {/* buttons */}
    {/* posts */}
    {/* settings */}
    </div>
    );
    }

    Instead, compose focused pieces:

    text
    UserProfile
    │
    ├── Avatar
    ├── UserDetails
    ├── FollowButton
    ├── Stats
    ├── PostList
    └── ProfileActions
    tsx
    function UserProfile() {
    return (
    <section>
    <Avatar />
    <UserDetails />
    <FollowButton />
    <Stats />
    <PostList />
    <ProfileActions />
    </section>
    );
    }

    Each component has a clearer responsibility.

    14. Composition Is Not Inheritance

    React generally encourages composition instead of inheritance for reusing UI behavior and structure.

    text
    Inheritance mindset:
    BaseComponent → AdvancedComponent → SpecialComponent
    Composition mindset:
    Component + Component + Component → Larger Component
    tsx
    function Dashboard() {
    return (
    <DashboardLayout>
    <Sidebar />
    <DashboardHeader />
    <Stats />
    <RecentOrders />
    </DashboardLayout>
    );
    }

    Components are assembled rather than extended through class inheritance.

    15. Composition Through Layout Components

    tsx
    function DashboardLayout({ children }: { children: React.ReactNode }) {
    return (
    <div className="dashboard">
    <Sidebar />
    <main>{children}</main>
    </div>
    );
    }
    <DashboardLayout>
    <DashboardHome />
    </DashboardLayout>
    <DashboardLayout>
    <OrdersPage />
    </DashboardLayout>

    The layout is reusable. The page content changes.

    16. Header + Content + Footer

    tsx
    function PageLayout({ children }: { children: React.ReactNode }) {
    return (
    <>
    <Header />
    <main>{children}</main>
    <Footer />
    </>
    );
    }
    function HomePage() {
    return (
    <PageLayout>
    <h1>Home</h1>
    <p>Welcome!</p>
    </PageLayout>
    );
    }
    function AboutPage() {
    return (
    <PageLayout>
    <h1>About</h1>
    <p>Learn about us.</p>
    </PageLayout>
    );
    }

    The common layout is reused through composition.

    17. Composition with Lists

    tsx
    const products = [
    { id: 1, name: "Banarasi Silk", price: 4999 },
    { id: 2, name: "Kanchipuram Silk", price: 6999 },
    ];
    function ProductList() {
    return (
    <section>
    {products.map((product) => (
    <ProductCard
    key={product.id}
    name={product.name}
    price={product.price}
    />
    ))}
    </section>
    );
    }
    text
    ProductList
    │
    ├── ProductCard
    └── ProductCard

    The list composes multiple instances of the same component.

    18. Composition with Custom Content

    tsx
    function Panel({ children }: { children: React.ReactNode }) {
    return <section className="panel">{children}</section>;
    }
    <Panel><ProductList /></Panel>
    <Panel><OrderSummary /></Panel>
    <Panel><UserSettings /></Panel>

    The panel doesn't care what its content is.

    19. A Real-World Example

    Imagine an online shopping application:

    text
    App
    │
    ├── Navbar
    │
    ├── HomePage
    │ ├── Hero
    │ ├── CategoryList
    │ │ ├── CategoryCard
    │ │ ├── CategoryCard
    │ │ └── CategoryCard
    │ └── ProductList
    │ ├── ProductCard
    │ ├── ProductCard
    │ └── ProductCard
    │
    └── Footer

    This is composition at multiple levels.

    20. Composition Makes Components Flexible

    tsx
    function Card({ children }: { children: React.ReactNode }) {
    return <div className="card">{children}</div>;
    }
    <Card><ProductCard /></Card>
    <Card><UserProfile /></Card>
    <Card><OrderSummary /></Card>

    The Card doesn't need to know what it contains. That's the key advantage.

    21. Do Not Put Everything Into Props

    You might be tempted to do:

    tsx
    <Card
    title="Product"
    description="..."
    image="/product.jpg"
    price={4999}
    buttonText="Buy"
    buttonColor="green"
    />

    Sometimes that's appropriate. But if content becomes complex, composition may be better:

    tsx
    <Card>
    <ProductImage />
    <ProductTitle />
    <ProductPrice />
    <BuyButton />
    </Card>

    Composition can make the API simpler.

    22. Props vs Composition: Practical Rule

    Use props when passing values or configuration:

    tsx
    <Button variant="danger">Delete</Button>

    Use composition when you want to control or replace pieces of UI:

    tsx
    <Card>
    <ProductInfo />
    <Button>Add to Cart</Button>
    </Card>

    Use both when appropriate:

    tsx
    <Card variant="featured">
    <ProductInfo />
    <Button size="large">Buy Now</Button>
    </Card>

    23. Composition and Reusability Work Together

    text
    Reusable Components
    ↓
    Small building blocks
    ↓
    Composition
    ↓
    Larger UI
    ↓
    Complete application
    text
    Button
    ↓
    ProductCard
    ↓
    ProductList
    ↓
    ProductPage
    ↓
    Application

    Each level composes smaller pieces.

    24. Avoid the Giant Component

    A common beginner pattern:

    tsx
    function App() {
    return (
    <div>
    {/* navbar */}
    {/* hero */}
    {/* products */}
    {/* reviews */}
    {/* cart */}
    {/* checkout */}
    {/* footer */}
    </div>
    );
    }

    As the application grows, this becomes difficult to maintain. Instead:

    tsx
    function App() {
    return (
    <>
    <Navbar />
    <Hero />
    <ProductList />
    <Reviews />
    <Cart />
    <Checkout />
    <Footer />
    </>
    );
    }

    Much easier to understand.

    25. Composition Does Not Mean "Make Everything Tiny"

    You shouldn't create endless micro-components just because each piece technically could be a component.

    Good composition creates meaningful boundaries, like ProductCard, ProductList, and ProductPage.

    26. A Good Composition Strategy

    When building a component, ask:

    1. What is this component responsible for?
    2. What should it control internally?
    3. What should the parent control?
    4. What content should be customizable?
    5. Should that customization use props or children?
    6. Can smaller components make this easier to understand?

    These questions lead to better component design.

    27. Complete Example

    tsx
    // Card.jsx
    function Card({ children }: { children: React.ReactNode }) {
    return <article className="card">{children}</article>;
    }
    // ProductInfo.jsx
    function ProductInfo({ name, price }: { name: string; price: number }) {
    return (
    <>
    <h2>{name}</h2>
    <p>INR {price}</p>
    </>
    );
    }
    // Button.jsx
    function Button({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) {
    return <button onClick={onClick}>{children}</button>;
    }
    // ProductCard.jsx
    function ProductCard({
    name,
    price,
    onBuy,
    }: {
    name: string;
    price: number;
    onBuy?: () => void;
    }) {
    return (
    <Card>
    <ProductInfo name={name} price={price} />
    <Button onClick={onBuy}>Add to Cart</Button>
    </Card>
    );
    }
    text
    ProductCard
    │
    └── Card
    │
    ├── ProductInfo
    │
    └── Button

    This is component composition in practice.

    28. The Most Important Pattern

    Get comfortable with this:

    tsx
    function Layout({ children }: { children: React.ReactNode }) {
    return (
    <div>
    <Header />
    {children}
    <Footer />
    </div>
    );
    }
    <Layout><HomePage /></Layout>
    <Layout><ProductsPage /></Layout>
    <Layout><CheckoutPage /></Layout>

    The layout stays the same. The content changes.

    29. Interview Questions

    Q1. What is component composition?

    Component composition is the practice of building larger React components by combining smaller, focused components.

    Q2. What is the children prop?

    children is a special React prop that represents the content placed between a component's opening and closing tags.

    tsx
    <Card>
    <h2>Hello</h2>
    </Card>
    // The <h2> is received by Card through children.

    Q3. Why is composition useful?

    It keeps components small, reusable, flexible, and focused on specific responsibilities.

    Q4. How is composition different from inheritance?

    Composition combines components to create larger UI. Inheritance extends behavior from a base class. React generally favors composition for UI reuse.

    Q5. When should you use children?

    Use children when a component should provide a wrapper, layout, or structural behavior while allowing the parent to control the content inside it.

    30. Key Mental Model

    text
    SMALL COMPONENTS
    ↓
    ┌─────┴─────┐
    ↓ ↓
    Button Card
    ↓ ↓
    └─────┬─────┘
    ↓
    ProductCard
    ↓
    ProductPage
    ↓
    App

    React applications are essentially compositions of components.

    The three concepts you've learned now fit together:

    text
    Props
    ↓
    Pass data and behavior
    Reusability
    ↓
    Use components repeatedly
    Composition
    ↓
    Combine components into larger UI

    Once you understand these three ideas, you're moving from simply writing JSX to actually designing React applications.

    Ready to mark this lesson complete?Track your journey across the entire course.