DEV Community

ncphillips
ncphillips

Posted on

The React "Named Children" Pattern

(Originally published on ncphi.dev)

React Components for wrapping content often use the children pattern. For example, this <Card> wraps the text "Hello World":

<Card>Hello World</Card>

The size of the <Card> could be set with a prop:

<Card size="large">Hello World</Card>

This pattern works if <Card> has just one content section but not if it has multiple. In that case the content might be provided by props instead of children:

<Card
  size="large"
  title="Hello World"
  subtitle="This is a basic example"
  body="Here is where a lot more text would go."
/>

Unfortunately this makes unfamiliar components hard to understand since prop might configure the appearance of the <Card> or defines its content. It also becomes messy when the content is not plain text:

<Card
  size="large"
  title="Hello World"
  subtitle={
    <>
      This is a basic <strong>example</strong>
    </>
  }
  body="Here is where a lot more text would go."
/>

The Named Children pattern helps with the mixing of concerns. Instead of setting children as content it's set as an object that maps section names to content. This approach separates content from config making it easier to guess each prop's purpose.

<Card size="large">
{{
  title: "Hello World"
  subtitle: <>This is a basic <strong>example</strong></>
  body: "Here is where a lot more text would go."
}}
</Card>

The children can then be used inside <Card> as any other object:

function Card({ size = "medium", children }) {
  return (
    <div className={size}>
      <h2>{children.title}</h2>
      <h3>{children.subtitle}</h3>
      <p>{children.body</p>
    </div>
  )
}

The Named Children pattern is a promising approach to separating concerns in React Components making them easier to read and easier to change.

(Originally published on ncphi.dev)

Top comments (1)

Collapse
 
kieranbenton profile image
Kieran Benton

Problem with this is that the object you're creating the children inside of us gets recreated on EACH RENDER of the parent - which can lead to subtle memoisation bugs further down the line. I don't have a solution for this yet - looking for answers apart from just including the children as top level props instead!