Children.count signature and return value
Children.count(children) takes the children prop and returns the number of nodes inside these children. Empty nodes (null, undefined, and Booleans), strings, numbers, and React elements count as individual nodes. Arrays don't count as individual nodes, but their children do. The traversal does not go deeper than React elements: they don't get rendered, and their children aren't traversed. Fragments don't get traversed.
Children.forEach signature and parameters
Children.forEach(children, fn, thisArg?) runs a function for each child in the children data structure. Parameters: children (the children prop), fn (the callback function called with child as first argument and index as second argument, starting at 0), and optional thisArg (the 'this' value for the fn function call). Returns undefined.
Children.map signature and parameters
Children.map(children, fn, thisArg?) maps or transforms each child in the children data structure. Parameters: children (the children prop), fn (the mapping function called with child as first argument and index as second argument, must return a React node), and optional thisArg (the 'this' value for the fn function call).
Children.map return value
Children.map returns null or undefined if children is null or undefined. Otherwise, returns a flat array consisting of the nodes returned from the fn function. The returned array will contain all nodes returned except for null and undefined.
Children.map key behavior
Children.map automatically combines the keys on the returned elements with the keys on the children passed to it. If you return an element or an array of elements with keys from fn, the returned elements' keys will be automatically combined with the key of the corresponding original item from children. When you return multiple elements from fn in an array, their keys only need to be unique locally amongst each other.
Children.map traversal and node counting
Children.map traverses the children data structure where empty nodes (null, undefined, and Booleans), strings, numbers, and React elements count as individual nodes. Arrays don't count as individual nodes, but their children do. The traversal does not go deeper than React elements: they don't get rendered, and their children aren't traversed. Fragments don't get traversed.
Children.only signature and return value
Children.only(children) asserts that children represent a single React element. Takes children (the children prop) as parameter. If children is a valid element, returns that element. Otherwise, throws an error.
Children.only throws on arrays
Children.only always throws if you pass an array (such as the return value of Children.map) as children. It enforces that children is a single React element, not that it's an array with a single element.
Children.toArray signature and return value
Children.toArray(children) creates a flat array out of the children data structure. Takes children (the children prop) as parameter. Returns a flat array of elements in children.
Children.toArray omits empty nodes and recalculates keys
Children.toArray omits empty nodes (null, undefined, and Booleans) in the returned array. The returned elements' keys will be calculated from the original elements' keys and their level of nesting and position. This ensures that flattening the array does not introduce changes in behavior.
Children API - children prop is opaque
The children data structure in React is considered opaque. You should not assume it's an array or any other particular data type. This is why you should use the Children methods if you need to transform it. In practice, the children data structure is often represented as an array internally, but if there is only a single child, React won't create an extra array to avoid unnecessary memory overhead.
Children API does not include rendered component output
The children data structure does not include rendered output of the components passed as JSX. When you pass a component like <MoreRows /> as a child, the Children methods see only that one component element, not the elements that MoreRows renders. There is no way to get the rendered output of an inner component when manipulating children.
Children API usage is uncommon and can lead to fragile code
Using the Children API is uncommon and can lead to fragile code. When you pass children to a component in JSX, you don't usually expect the component to manipulate or transform the individual children. It's usually better to use alternative solutions.
Children.map example with wrapper
Example showing Children.map wrapping each child in a div: import { Children } from 'react'; function RowList({ children }) { return ( <div className="RowList"> {Children.map(children, child => <div className="Row"> {child} </div> )} </div> ); }
Children.count example
Example showing Children.count to display total number of children: import { Children } from 'react'; function RowList({ children }) { return ( <> <h1>Total rows: {Children.count(children)}</h1> ... </> ); }
Children.forEach example with separator
Example showing Children.forEach to build an array with separators: import { Children } from 'react'; function SeparatorList({ children }) { const result = []; Children.forEach(children, (child, index) => { result.push(child); result.push(<hr key={index} />); }); return result; }
Children.toArray example with reverse
Example showing Children.toArray to convert children to array and reverse: import { Children } from 'react'; export default function ReversedList({ children }) { const result = Children.toArray(children); result.reverse(); return result; }
Children API for manipulating JSX children prop
The Children API lets you manipulate and transform the JSX received as the children prop. It is a legacy API with alternatives available.