Skip to content

Wrap a Component Inside Another in React

React/

Similarly to how you can wrap one HTML element in another, you can also do that with React components. It’s possible because of composition.

In React, composition is the ability to pass components to other components as props. You can create generic container components that wrap other components like cards, modals and sidebars.

To wrap a component in another component in React you have to use the built-in children prop.

Here’s an example of a generic card component that can contain any content.

export default function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

Since you don’t know ahead of time what the content is going to be, you need to pass the Card component a children prop.

The children prop contains everything you put between the opening and closing tags of a component. Just like in HTML.

import Card from 'src/components/Card';

export function UserForm() {
  return (
    <Card>
      <h2>Edit Info</h2>
      <form>
        {/* ✂️ */}
      </form>
    </Card>
  );
}

export function UserInfo() {
  return (
    <Card>
      <h2>User Info</h2>
      <p>
        {/* Name: ✂️ */}
      </p>
    </Card>
  );
}

Here is some explanation of what’s happening:

  • Two components UserForm and UserInfo, reuse Card component to share one look
  • Each component passes its own content to the Card component
  • The Card component can access that content through its children prop

This results in both components — UserForm and UserInfo — rendering Card component wrapped around their content.

Wrapping content UserForm and UserInfo components in Card component to share one style

Using Composition in React

One of the most common uses for composition in React is layouts.

When your application has many pages sharing a common look and following the same structure, you should create a layout component.

export default function Layout({ children }) {
  return (
    <>
      <header>
        <p>Site Name</p>
      </header>
      <main>{children}</main>
      <footer>
        <p>&copy; 2022 Site Name</p>
      </footer>
    </>
  );
}

Now, if you have multiple page components that you can navigate between, they all can reuse this Layout component.

export function HomePage() {
  return (
    <Layout>
     <h1>Home</h1>
    </Layout>
  );
}

export function UserPage() {
  return (
    <Layout>
      <h1>User</h1>
    </Layout>
  );
}

Passing Components as Props

In a page layout, the header and footer usually remain the same while only the main content changes.

But, what if you wanted do something like this:

<header>
  {header}
</header>
<main>{children}</main>
<footer>
  {footer}
</footer>

This pattern of having multiple adjustable parts of a wrapper component is called slots in other frameworks. It’s not exactly the same in React, but we can achieve similar functionality.

To achieve the functionality of “slots” in React, you can pass as many components through props as you want. You don’t have to rely on just the children prop.

For example, you can change the header, footer, both or none of the following Card component.

export default function Card({ children, header, footer }) {
  return (
    <>
      {header && <header>{header}</header>}
      <section>{children}</section>
      {footer && <footer>{footer}</footer>}
    </>
  );
}

You can pass anything that React can render through header and footer. It doesn’t have to be just simple data types.

<Card>
  <p>Just content</p>
</Card>

<Card header="Heading text">
  <p>Content with a heading</p>
</Card>

<Card header={<h2>Heading</h2>} footer="Footer text">
  <p>Content with a heading and a footer</p>
</Card>

<Card footer={<Footer />}>
  <p>Content with a footer</p>
</Card>

As you can see, header and footer props can contain JSX, plain text and even components. Anything you put between opening and closing tags of Card goes into children prop. That’s how you can have many outputs in one wrapper component.

Achieving multiple variations of Card component using the slots pattern

Thanks to the versatility of Card component and composition, you can create many different Card variations.