React Children And Iteration Methods
About The Author
Arihant Verma is a Software Engineer based in India. He likes to read open source code and help others understand it. He’s a rich text editors fanatic. His …
In this article, we’ll discuss and learn about the use case of iterating over React
children and the ways to do it. In particular, we will deep dive into one of the utility methods,
React.Children.toArray, that React gives us, which helps to iterate over the
children in a way which ensures performance and determinism.
The most obvious and common prop that developers work with within React is the
children prop. In the majority of cases, there is no need to understand how the
children prop looks like. But in some cases, we want to inspect the
children prop to maybe wrap each child in another element/component or to reorder or slice them. In those cases inspecting how the
children prop looks like becomes essential.
In this article, we’ll look at a React utility
React.Children.toArray which lets us prepare the
children prop for inspection and iteration, some of its shortcomings and how to overcome them — through a small open-source package, to keep our React code function the way it is deterministically supposed to behave, keeping performance intact. If you know the basics of React and have at least an idea about what the
children prop in React is, this article is for you.
While working with React, most of the time we do not touch the
children prop any more than using it in React components directly.
But sometimes we have to iterate over the
children prop so that we can enhance or change the children without having the user of the components explicitly do it themselves. One common use case is to pass the iteration index-related information to child components of a parent like so:
Here we’re doing the following:
The user of
BreadcrumbItem doesn’t have to worry about which children should have links and how they should be styled. Inside the
Breadcrumbs component, it automatically gets handled.
This pattern of implicitly passing in props and/or having
state in the parent and passing the state and state changers down to the children as props is called the compound component pattern. You might be familiar with this pattern from React Router’s
Switch component, which takes
Route components as its children:
Now that we have established that there are needs where we have to iterate over
children prop sometimes, and having used two of the children utility methods
React.Children.toArray, let’s refresh our memory about one of them:
Deep-dive into front-end accessibility with Carie Fisher in her upcoming Smashing workshop on . With best practices and guidelines on accessibility, assistive technology and inclusive design patterns. Online, and live.
Let’s start by seeing with an example what this method does and where it might be useful.
We have a
Debugger component, which does nothing much in terms of rendering — it just returns
children as is. But it does log two values:
If you open up the console, you’d be able to see the difference.
Let’s read the method’s documentation in React docs to make sense of what is happening.
React.Children.toArray returns the
children opaque data structure as a flat array with keys assigned to each child. Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice
children before passing it down.
Let’s break that down:
The first point says that that
children (which is an opaque data structure, meaning it can be an object, array, or a function, as described earlier) is converted to a flat array. Just like we saw in the example above. Additionally, this GitHub issue comment also explains its behavior:
React.Children.toArray) does not pull children out of elements and flatten them, that wouldn’t really make any sense. It flattens nested arrays and objects, i.e. so that
[['a', 'b'],['c', ['d']]] becomes something similar to
['a', 'b', 'c', 'd'].
Let’s see what the second point (‘With keys assigned to each child.’) says, by expanding one child each from the previous logs of the example.
Expanded Child From
Expanded Child From
As you can see, besides flattening the
children prop into a flat array, it also adds unique keys to each of its children. From the React docs:
.toArray method might change the order and place of
children, it has to make sure that it maintains unique keys for each of them for reconciliation and rendering optimization.
Let’s give a little bit more attention to
so that each element’s key is scoped to the input array containing it., by looking at the keys of each element of the second array (corresponding to
As you can see that the fruits, which were originally a nested array inside the original
children array, have keys that are prefixed with
.2 corresponds to the fact that they were a part of an array. The suffix, namely
:2 are corresponding to the React elements’ (fruits) default keys. By default, React uses the index as the key, if no key is specified for the elements of a list.
So suppose you had three level of nesting inside
children array, like so:
The keys will look like
$3 suffixes are because of the original keys put on the React elements in an array, otherwise React complains of lack of keys ? .
From whatever we’ve read so far we can come to two use cases for
If there’s an absolute need that
children should always be an array, you can use
React.Children.toArray(children) instead. It’ll work perfectly even when
children is an object or a function too.
If you have to sort, filter, or slice
children prop you can rely on
React.Children.toArray to always preserve unique keys of all the children.
There’s a problem with
React.Children.toArray ?. Let’s look at this piece of code to understand what the problem is:
If you see what gets rendered for the children of the fragment, you’ll see that both of the links get rendered inside one
li tag! ?
This is because doesn’t traverse into fragments. So what can we do about it? Fortunately, nothing ? . We already have an open-sourced package called . It’s a small function that does its magic.
Let’s see what it does. In pseudo-code (these points are linked in the actual code below), it does this:
Let’s retry our previous example to use this function and see for ourselves that it fixes our problem.
Woooheeee! It works.
As an add-on, if you are new to testing — like I am at the point of this writing — you might be interested in 7 tests written for this utility function. It’ll be fun to read the tests to deduce the functionality of the function.
The Long Term Problem With
The problem with using
Children methods to change
children behavior is that they only work for one level of nesting of components. If we wrap one of our
children in another component, we lose composability. Let’s see what I mean by that, by picking up the first example that we saw — the breadcrumbs.
Although our new component
<BreadcrumbItemCreator /> rendered, our
Breadcrumb component doesn’t have any way to extract out the
link prop from it, because of which, it doesn’t render as link.
To fix this problem React team had come with — now defunct — experimental API called react-call-return.
Ryan Florence’s Video explains this problem in detail, and how
react-call-return fixed it. Since the package was never published in any version of React, there are plans to take inspiration from it and make something production-ready.
To conclude, we learned about:
You might also be interested in reading how to use other
Children methods to do everything you can do with
children in Max Stoiber’s blog post React Children Deep Dive.
This content was originally published here.