Back to all notes

Children Pattern: Flexible Slots Without Extra Props

Pass UI through the children prop to keep parents flexible and children independent.

2 min read

Introduction

The children pattern lets a component define structure while consumers provide content via the children prop. It’s a simple way to create flexible layouts without extra props.

Why this matters

Sometimes a component should define structure but not content. Using the children prop lets consumers decide what goes inside, without coupling content to the parent. It also avoids re‑renders caused by the parent owning the child’s state.

The problem

We want to show or hide content based on a flag, but keep the wrapper generic and reusable.

Inefficient approach

Conditional rendering scattered in parents quickly duplicates logic and structure:

import { useState } from "react";

function App() {
  const [showContent, setShowContent] = useState(true);
  const content = "This is the content";

  return (
    <div>
      <h1>Children Pattern</h1>
      <button onClick={() => setShowContent(!showContent)}>Toggle Content</button>
      {showContent ? <p>{content}</p> : null}
    </div>
  );
}

export default App;

The solution

Create a wrapper that renders its children only when showContent is true.

import { useState } from "react";

function Wrapper({ children, showContent }) {
  if (!showContent) return null;
  return (
    <div>
      <p>{children}</p>
    </div>
  );
}

function App() {
  const [showContent, setShowContent] = useState(true);
  const content = "This is the content";

  return (
    <div>
      <h1>Children Pattern</h1>
      <button onClick={() => setShowContent(!showContent)}>
        Toggle Content
      </button>
      <Wrapper showContent={showContent}>{content}</Wrapper>
    </div>
  );
}

export default App;

Step-by-step

  1. Define a Wrapper that accepts children and showContent.
  2. Return null early when showContent is false.
  3. Render children when true—avoid coupling content to the wrapper.
  4. In the parent, toggle showContent with a button.
  5. Pass any content as children to keep the API flexible.

Tips

  • Children can be any renderable value—strings, elements, fragments, or even functions (see the next lesson).
  • Keep wrappers minimal. If you add logic, document it and keep the contract clear.
  • Prefer early returns for conditional rendering; it reads better.

Knowledge base

Problem snippet:

{showContent ? <p>{content}</p> : null}

Solution snippet:

<Wrapper showContent={showContent}>{content}</Wrapper>