One of the features that drew me in to React was the explicit intention by its authors to create an API with a minimal surface area. This is a great goal, because it allows you to keep the full React API in your head when developing your application with React. Writing React code is often focused on creating components and using the component API and lifecycle methods, but there are a few other useful top-level utilities provided in the React API. Below I’ll cover the
React.Children methods for handling the
this.props.children opaque data structure and how I’ve used them in my React apps.
The release notes for
React.cloneElement discuss a common pattern that consists of using
React.Children.map to map over the
children prop passed to a component and returning a cloned version of each child with additional props passed in. This allows you to pass props down from a parent component to a child component without the parent needing to explicitly render that child. This can be a big help in building reusable React components.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
In this example, the
<PostHeader> elements don’t need to know about their styles, and indeed these components could be used elsewhere without this salmon-inspired color palette. (CSS is also a solution here 😄.) Similarly, the
<Salmonize> component does not need to be aware of the fact that it is rendering the
<PostHeader> components, but it is still able to pass its props along to those child components.
It’s definitely a bit tricky to write truly reusable components in React. If you’re having trouble with this, then this “map and clone” trick can probably help you on the way to achieving this elusive goal.
React.Children.map, but has no return value. I haven’t used this method as I haven’t had the need to loop over a component’s children and do something other than augment props or render UI. There is a pretty elegant use case for this in Pete Hunt’s
rwb repo here.
This method returns the number of child components in the
children argument passed to it. Again, I haven’t come across the use case for this one personally. Most of the use cases I came across in a cursory Github search were simply confirming whether or not any children had been passed to a component, as in the above example from Pete Hunt.
This can come in handy when you want to ensure that a component only has one child, and throw an error if this condition is not met. There’s a good example of this in a previous version of Cheng Lou’s
react-radio-group component here:
1 2 3 4 5 6 7 8 9
The example app in the repo complies with this contract.
This method converts the
React.Children.toArray came in handy for me recently when I wanted to render a list of items with a divider element interspersed between them. This led me to create an
<IntersperseDividers> component to accomplish just that.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
I got caught on this component for a moment because of an error thrown when I tried to directly return an array of elements. I fixed it by wrapping the array returned by
React.Children.toArray() in a
<div>, just like in the
React.Children.map example above. You wouldn’t need this wrapping
<div> if the content was inlined in the
<List> component, so it’s a tradeoff for better component reusability at the expense of increased divitis.
If you haven’t read through it before, I’d recommend taking a minute to skim through the top-level API section of the React docs. Though the API surface area is small, there are some hidden gems within.