The Children Prop Pattern in React

While it is one of the most underused patterns in React, the Children Prop Pattern is a powerful tool for building reusable components. But it has another aspect that makes it even more interesting to understand and use: re-renders optimization.

4 min read - 781 words

Cover for The **Children Prop Pattern** in React

The Children Prop Pattern is the most underused and underappreciated pattern in React. It's the only pattern that matters. For two reasons

  • it improves the readability of component trees ;
  • it improves performance.

So... what is the Children Prop Pattern ?

Look at the code below:

typescript
function Container() {
return (
<div className="container">
<UserList />
</div>
);
}
function UserList() {
return (
<div className="user-list">
<UserItem />
<UserItem />
<UserItem />
</div>
);
}

We can see that the UserItem elements do not depend on any local variables inside the UserList component.

It is a perfect candidate for the children prop pattern.

To use the children prop pattern, we rewrite the above code to move the UserItem elements above in the tree and add a children prop to the UserList component. It gives us the following:

typescript
function Container() {
return (
<div className="container">
<UserList>
<UserItem />
<UserItem />
<UserItem />
</UserList>
</div>
);
}
function UserList({ children }: { children: React.ReactNode }) {
return <div className="user-list">{children}</div>;
}

The children prop is a special prop in React: React automatically populates it with the content between the opening and closing tags of the component.

Composition

The children prop pattern is a form of composition. It allows you to compose components together. It allows you to build complex components from simpler ones.

It improves the readability and maintainability of your code. You can avoid props drilling with this pattern and even prevent using the Context API.

Can I use this pattern every time?

Short answer, no.

As I said above, this pattern only works when the children's elements do not depend on their parent component's internal variables.

For instance, we cannot rewrite the following to use this pattern. The div element and the UserItem elements depend on the selected variable.

typescript
function UserList() {
const [selected, setSelected] = React.useState(0);
return (
<div
className={classnames("user-list", {
"has-selection": selected !== null,
})}
>
<UserItem selected={selected === 0} />
<UserItem selected={selected === 1} />
<UserItem selected={selected === 2} />
</div>
);
}

Do I need to use the children prop name?

The children prop pattern does not limit itself to the children prop name. You could use any name to pass down elements like kids or element.

The only difference for the children prop is that you have the tree syntax offered by JSX.

For instance, the React Router library uses the element prop name to pass down elements.

typescript
function App() {
return (
<Router>
<Route path="/users" element={<UserList />} />
</Router>
);
}

Performance

Performance-wise, this pattern is exciting...

Let's consider the following code below:

typescript
function Container() {
return (
<div className="container">
<UserList>
<UserItem />
<UserItem />
<UserItem />
</UserList>
</div>
);
}
function UserList({ children }: { children: React.ReactNode }) {
const [count, setCount] = React.useState(0);
return (
<div className="user-list">
<button onClick={() => setCount(count + 1)}>Click me</button>
{children}
</div>
);
}

Before continuing below, can you answer the following question:

when the UserList element updates due to its state updating, do the UserItem elements re-render?

I'll let you think about it for a moment.

The answer is no. The UserItem elements will not re-render because they are not part of the UserList component tree. They are part of the Container component tree.

When the UserList component updates, it uses the prop children to render its content. The children prop is stable between UserList re-renders due to count state updates. It is the same reference, object, in short elements. So the React reconciliation algorithm will not re-render the UserItem elements.

Yes, you read it right, the children prop is not re-rendered when the component re-renders : the prop children comes from outside the component.

Do not believe me ? Try it in this CodeSandbox.

If you check the Profiler tab, you will see that the UserItem elements are not re-rendered when the UserList component re-renders.

That is why I say that a component re-renders when the parent that instantiates it re-renders. In our case, the parent of the UserItem elements is the UserList component, but the parent that instantiates them is the Container component. So the UserItem elements will re-render when the Container component re-renders.

Take a moment to think about this in terms of performance.

Conclusion

With this article, you should now understand how powerful the Children Prop Pattern is and how it can help you improve your codebase and components.

Did you like this article? Don't hesitate to share it or leave a comment below 🙂.

Formations

React Query1 jour

React Query

Exploitez des données serveur rapidement

En savoir plus
React Avancé3 jours

React Avancé

Maîtrisez le développement d'applications complexes avec React

En savoir plus

Articles

Go to article
**Understanding React Hooks:** JavaScript Fundamentals

Understanding React Hooks: JavaScript Fundamentals

Hooks are hugely related to more general JavaScript concepts like closures, memoization, and primitive vs. reference values. Correctly understanding these concepts and their role in React Hooks is essential to use them properly.
ReactHooksFundamentals
September 26, 2022 — 11 min read
Go to article
All you need to know about React.useState

All you need to know about React.useState

A complete guide to React.useState hook mechanisms.
ReactHooksPerformance
August 10, 2022 — 8 min read