Reputation: 6112
I'm well aware of the reasons why one needs to add a key
prop when creating dynamic children in React. What's intriguing to me is the behavior of the below two pieces of code
This iterates over children
using just Array#map
const App = () => {
return (
<Parent>
<span>Child 1</span>
<span>Child 2</span>
<span>Child 3</span>
</Parent>
);
};
const Parent = ({ children }) => {
return children.map(child => (
<div style={{ background: "lightblue" }}>{child}</div>
));
};
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id="app">
This uses React.Children.map
to do the same
const App = () => {
return (
<Parent>
<span>Child 1</span>
<span>Child 2</span>
<span>Child 3</span>
</Parent>
);
};
const Parent = ({ children }) => {
return React.Children.map(children, child => (
<div style={{ background: "lightblue" }}>{child}</div>
));
};
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id="app">
The first snippet produces a warning
Each child in an array or iterator should have a unique "key" prop
whereas the second one doesn't produce any. So the two questions I have are:
React.Children.map
auto-generate keys for the elements we pass through it?Upvotes: 22
Views: 8921
Reputation: 281950
React.Children.map
takes into account thekey
that you have provided for the child components and adds a prefix to them, if the key is not provided to the children components, it adds a Implicit key determined by the index in the set while iterating to the mapped object
Below is a excerpt from the mapChildren
function form React src
function getComponentKey(component, index) {
// Do some typechecking here since we call this blindly. We want to ensure
// that we don't block potential future ES APIs.
if (
typeof component === 'object' &&
component !== null &&
component.key != null
) {
// Explicit key
return escape(component.key);
}
// Implicit key determined by the index in the set
return index.toString(36);
}
Upvotes: 18