A Complete Guide To props.children In React
Tags: javascript, programming, react, technology
Published: 2024-01-19 20:19:40

I developed with React for months without fully understanding the real power of the React component model. One day I decided to dive into composition, and this is what I learned.

## React Components and Children

In React, **a component can have one, many, or no children**. Great, but wait — what are "children"? Let's explain with an example:

```javascript
<Profile>
  <ProfileImage src="/asset/profile-img.png" />
  <ProfileDetails name="Antonello" surname="Zanini" />
</Profile>
```

The `Profile` component **has two children**: `ProfileImage` and `ProfileDetails`, while these two **have no children**.

> _"In JSX expressions that contain both an opening tag and a closing tag, the content between those tags is passed as a special prop: `props.children`"_ — [React documentation](https://reactjs.org/docs/jsx-in-depth.html#children-in-jsx)

Essentially, `props.children` is a special prop, automatically passed to every component, that can be used to render the content included between the opening and closing tags when invoking a component. These kinds of components are identified by the [official documentation](https://reactjs.org/docs/composition-vs-inheritance.html#containment) as "boxes".

## Identifying Components by JSX Syntax

In [React's JSX](https://reactjs.org/docs/jsx-in-depth.html#children-in-jsx), **a component with children is always identified by an opening tag and a closing tag**. Each child must be placed between these two tags, just as we have seen above. When a component has no children, you can invoke it with either `<MyComponent></MyComponent>` or `<MyComponent/>`, but the latter syntax is generally preferred. The purpose of [self-closing tags](https://zhenyong.github.io/react/tips/self-closing-tag.html) is to make code shorter and easier to read.

## `props.children` in Actions

Let's assume that we want to create an `ImageSlider` component. Our goal is to invoke the component just like this:

```javascript
<ImageSlider>
  <img src="/assets/img-1.pg" />
  <img src="/assets/img-2.pg" />
  <img src="/assets/img-3.pg" />
</ImageSlider>
```

As you can see, `ImageSlider` is composed of several `<img ... />` which can be accessed and rendered through `props.children`.

```javascript
export default function ImageSlider(props) { 
    return (
      <div className="img-slider">
        {props.children}
      </div>
    );  
}
```

Thanks to `props.children` **we can nest our content inside a component, just like we nest common HTML elements**.

## What Types of Content Are Allowed for `props.children`?

The content passed to a component through `props.children` [can include](https://flow.org/en/docs/react/types/#toc-react-node) `undefined`, `null`, a [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean), a [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), a [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), a [React element](https://flow.org/en/docs/react/types/#toc-react-element), or an array of any of these types recursively. It can also be a function returning one of these types.  

Please note that, as mentioned in the [React documentation](https://reactjs.org/docs/jsx-in-depth.html#booleans-null-and-undefined-are-ignored), `false`, `null`, `undefined`, and `true` are valid children, but **they will be ignored and not rendered**. If you want `false`, `true`, `null`, or `undefined` to be rendered, you must first [convert it to a string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#String_conversion):

```javascript
<MyComponent>
  { String(undefined) }
</MyComponent>
```

## Why Is `props.children` So Important?

`props.children` allows us to compose components, and therefore our front-end interface as a consequence; harnessing the real power of the [React component model](https://reactjs.org/docs/thinking-in-react.html).

> "React has a powerful composition model, and **we recommend using composition instead of inheritance** to reuse code between components." — [_React documentation_](https://reactjs.org/docs/composition-vs-inheritance.html)

As covered in the [official documentation](https://reactjs.org/docs/composition-vs-inheritance.html#containment), you might sometimes need to fill multiple "holes" in a component. In such cases, instead of using `props.children`, defining multiple custom props may be the preferable approach; as shown in the following example:

```javascript
function SplitPane(props) {
  const { left, right } = props
  
  return (
    <div className="split-pane">
      <div className="left-pane">
        { left }      
      </div>
      <div className="right-pane">
        { right }      
      </div>
    </div>
  );
}
```

## React.Children

> _"[`React.Children`](https://reactjs.org/docs/react-api.html#reactchildren) provides utilities for dealing with the `props.children` opaque data structure"_ — [_React documentation_](https://reactjs.org/docs/composition-vs-inheritance.html)

Why is `props.children` an "opaque data structure"?

Because `props.children` can consist of **one, many, or no child elements**, which means that its value can be **a single child node, an array of child nodes, or** **`undefined`** **respectively**. Thanks to the `React.Children` API we can easily deal with `props.children` without taking each of its possible types into account. Thankfully, everything will be handled for us in the background.

At the time of writing, `React.Children` offers **five different utilities**:

- [map](https://reactjs.org/docs/react-api.html#reactchildrenmap)

- [forEach](https://reactjs.org/docs/react-api.html#reactchildrenforeach)

- [count](https://reactjs.org/docs/react-api.html#reactchildrencount)

- [only](https://reactjs.org/docs/react-api.html#reactchildrenonly)

- [toArray](https://reactjs.org/docs/react-api.html#reactchildrentoarray)

Let's see how we can use `React.Children` with an example. Let's say we want to add the special CSS class `img-special-class` to each of the children of the `ImageSlider` component. This can be done as follows:

```javascript
export default function ImageSlider(props) {
  const { children } = props

  return (
    <div className="img-slider">
      {
        React.Children.map(children, (child) =>
          React.cloneElement(child, {
              className: `${child.props.className} img-special-class`
            })
        )
      }
    </div>
  );
}
```

[`React.Children.map`](https://reactjs.org/docs/react-api.html#reactchildrenmap) allows us to iterate over `props.children` and transform each element according to the function passed as the second parameter. To achieve our goal, we used [`React.cloneElement`](https://reactjs.org/docs/react-api.html#cloneelement). This is because we needed to change the value of the `className` prop, but [**props are immutable in React**](https://stackoverflow.com/a/47471276), so we had to clone each child.

## Conclusion

Mastering `props.children` is essential to becoming a great React developer and beginning to harness the full potential of the React component model. `props.children` is one of React's most useful features, since it gives us the ability to render child components. Because of this, every developer should know how to use it properly.

I hope this article helps you master composition in React.
  
***
_The post "[A Complete Guide To props.children In React](https://writech.run/blog/a-complete-guide-to-props-children-in-react-c315fab74e7c/)" appeared first on [Writech](https://writech.run)._