FrontendPrep
Menu
Topics
Questions
Guides
Challenges
Soon
Back to React Questions
reactEasy

React: Component Composition and the children Prop

Learn component composition in React. Understand how to design reusable wrapper layouts, handle dynamic slots, and prevent prop drilling using the children prop.

React: Component Composition and the children Prop

A fundamental React design pattern question is:

What is component composition in React and how do you use the children prop? How does it help avoid prop drilling?

React encourages building UIs from small, isolated pieces of code called components. Rather than relying on inheritance, React utilizes composition. Interviewers look for your ability to design flexible component interfaces using the built-in composition capabilities:

  • The children Prop: How React automatically passes nested tags to child components.
  • Wrapper Components: Building generic containers like cards, modals, or page layouts.
  • Dynamic Slots: Passing components as standard named props to support multiple dynamic areas.
  • Decoupling State: How composition solves prop drilling by keeping state and view details split.

Let's explore component composition from first principles.


1. What is the children Prop?

In React, you can nest components inside one another just like standard HTML tags.

<Card>
  <h2>Title</h2>
  <p>Description text</p>
</Card>

When you do this, React automatically collects the nested elements and passes them to the <Card /> component under a special, built-in prop called children.

Inside the <Card /> component, you can render this prop anywhere in the JSX layout:

function Card({ children }) {
  return (
    <div className="card-container">
      {/* Renders the nested contents */}
      {children}
    </div>
  );
}

2. Creating Wrapper Components

Wrapper components are generic, reusable containers that manage layout styling, animations, or boundary contexts, leaving the actual nested contents to be configured by the consumer.

Consider a reusable modal dialog box:

function Modal({ title, isOpen, onClose, children }) {
  if (!isOpen) return null;
 
  return (
    <div className="modal-overlay">
      <div className="modal-content">
        <header className="modal-header">
          <h3>{title}</h3>
          <button onClick={onClose}>&times;</button>
        </header>
        
        {/* Composition slot for body content */}
        <div className="modal-body">
          {children}
        </div>
      </div>
    </div>
  );
}

By using children, the <Modal /> component doesn't care whether its body is a login form, a video player, or simple text. This makes it highly reusable.


3. Dynamic Slots Pattern

Sometimes, a single children prop is not enough because you need to place components in different visual locations (such as a header, sidebar, and footer). In React, you can solve this by passing components as standard named props.

This is called the slots pattern:

function PageLayout({ header, sidebar, content }) {
  return (
    <div className="page-grid">
      <header>{header}</header>
      <aside>{sidebar}</aside>
      <main>{content}</main>
    </div>
  );
}
 
// Usage:
<PageLayout 
  header={<Navbar />}
  sidebar={<NavigationMenu />}
  content={<DashboardGrid />}
/>

4. Solving Prop Drilling via Composition

Prop drilling occurs when you pass props through multiple levels of intermediate components just to get the data to a deeply nested child.

Before composition:

<App user={user}>
  <Dashboard user={user}>
    <ProfileCard user={user} />
  </Dashboard>
</App>

The <Dashboard /> component does not need user, but must accept and forward it.

After composition:

// App.tsx
<App>
  <Dashboard>
    <ProfileCard user={user} />
  </Dashboard>
</App>
 
// Dashboard.tsx
function Dashboard({ children }) {
  return <div className="dashboard-layout">{children}</div>;
}

Now, <Dashboard /> is a layout container that simply renders its children. We pass <ProfileCard user={user} /> directly inside App, completely bypassing the intermediate prop-drilling step!


Senior-Level Interview Answer

Component composition is a structural design pattern in React where smaller, isolated components are assembled to build complex user interfaces. It is primarily powered by the built-in children prop, which automatically captures nested JSX elements and allows components to act as generic layout wrappers (like cards, modals, or grid containers). Composition is a powerful tool to prevent prop drilling; by instantiating the leaf node component (which needs the data) at the parent container level and passing it down as a nested child, intermediate layout nodes remain decoupled from the data requirements. For complex layouts requiring multiple dynamic sections, React supports the slots pattern by passing element nodes as standard named props.


Common Interview Mistakes

❌ Relying on inheritance instead of composition

Coming from object-oriented programming backgrounds, developers sometimes look for a class-based inheritance model in React (e.g. extending components). React has a strict component composition model, and there are almost zero real-world scenarios where class inheritance is recommended.

❌ Attempting to mutate or directly inspect children

The children prop is an opaque data structure (it can be an object, an array, or even a function). Never try to access children[0].props directly, as this breaks easily. If you need to inspect or transform children, use the safe React.Children utilities (like React.Children.map).


Key Takeaways

  • Composition over Inheritance: React uses component composition instead of inheritance to build flexible, modular UIs.
  • Children Prop: Nested JSX elements are automatically gathered and passed to child components via the children prop.
  • Wrapper Pattern: Using composition enables developers to build generic layout templates (such as panels, modals, and tables) that remain independent of their content.
  • Slots Pattern: Pass components as standard named props (slots) when you need to position dynamic components in multiple separate areas.
  • Drilling Mitigation: Nesting leaf nodes directly at the root container level decouples intermediate layouts, resolving prop drilling.

Share this Resource

Help other developers level up by sharing this study guide.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.