That would work with the current version of React, 15.6.1 (and probably with prior versions as well). However, there is a slightly better way to achieve your goal with a small tweak, which would be delegating the lifting on a prop, rather than using directly the key
.
The reason is that the concept of a key is something that is controlled by React internals before your component gets created, so it falls into the implementation details category, with the consequence that future versions of React could break your code without you even noticing it.
Instead, you can use a prop on your Child
component, for instance id
, based on your assumption that each child does have some sort of unique value. Your code would result in:
const Child = props => <div>{props.name}</div>;
const Parent = props => {
return React.Children.map(props.children, c => {
return (<Decorator key={c.props.id}>
{c}
</Decorator>);
});
return (<div>
{wrappedChildren}
</div>);
}
const Consumer = props => {
let children = [0, 1, 2].map(num => {
return <Child id={num} name={num} />;
});
return <Parent>{children}</Parent>;
});
If you have a more complex structure and want to avoid passing props individually, the parent component should held the responsibility of generating unique ids for the children. You can follow the ideas explained in this answer https://stackoverflow.com/a/29466744/4642844.
Those are the steps I'd follow:
- Implement your own utility function or use an existing browser library to generate unique ids.
Implement componentWillMount
in your Parent
component to create an array of unique ids. You can use an internal member class variable instead of local state
. It would be something like:
componentWillMount() {
this.uuids = React.Children.map(() => uuid());
}
Inside your Parent
render, assign each key to the Decorator component in the following way.
render() {
return React.Children.map(props.children, (c, i) => {
return (<Decorator key={this.uuids[i]}>
{c}
</Decorator>);
});
}
Some useful links:
http://mxstbr.blog/2017/02/react-children-deepdive/
https://medium.com/@dan_abramov/react-components-elements-and-instances-90800811f8ca