-
Notifications
You must be signed in to change notification settings - Fork 48.6k
React.Children.map does not return an Array or Array-like object #2872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
this confuses me too |
In programming React could provide a converter between Children and Array. It'd probably look something like this: React.Children.toArray = function(children){
var isElement = React.isValidElement(children);
if (Array.isArray(children)){
return children.slice();
}
// single child
else if (!children || typeof children !== 'object' || isElement) {
// avoid the warning about missing key prop
if (isElement && !children.key) {
return [React.cloneWithProps(children, {key: 0})];
}
return [children];
}
// {a: <div />} -> [<div key="a" />]
else {
return Object.keys(children).map((key) => {
// assuming a directly set key overrides the object's key (haven't tested it)
if (!children[key].key) {
var props = {key: key};
return React.cloneWithProps(children[key], props));
}
return children[key];
});
}
} |
Thanks @brigand for a great reply. One thing that confuses me, however, is that I'll typically invoke
In this case, I do see your point, and it's fair for the map function to not be obligated to return arrays. But it seems problematic that it accepts arrays (thus violating the formal definition of the map method you provided). I think a larger question I have around React Elements as children is how we are meant to interact with them if we have an opaque interface. I've updated a jsfiddle here which tries to demonstrate this -- it wants to shuffle a list of children, each of which are React Elements. I would love to get some thoughts on what the best practice is for solving this problem. Your converter from Children to Array seems plausible, I'm just wondering why it hasn't been a problem for others yet -- it makes me think I'm just missing some bigger picture here :) Cheers! |
So... there is a way to do that, but it's complicated and involves React.Children.forEach and React.Children.count, and storing the sorted indexes in state, and handling changing the array of indexes in componentWillReceiveProps. The better way to do it is just sort the data in the parent component. I'm glad it's so complicated to do in a child, because sorting elements doesn't make a lot of sense (you sort data). For fun, here's an implementation. As a side note, you shouldn't store elements in state. An element should only be used once. If I update the text of a ListItem, it wouldn't show in the UI because your component still renders the same elements. |
brigand, why are you using slice in your code above?
|
@dyscrete if I just returned the array then sometimes (but not always) |
@brigand Thanks for the explanation and I'm familiar with use of |
map now always returns an array in 0.14. |
Hey there,
I'm trying to use
React.Children.map
in conjunction withReact.addons.cloneWithProps
to create a copy of my children. However, it's surprising behavior to find that map does not return an array as a typical map function would.The value I see in returning an array would be enabling one to perform array operations on a collection of children, such as reordering/splicing, inserting new elements, etc. Since it doesn't return an array, and the children are meant to be an opaque data structure, it's unclear to me what the best practice is for doing this type of thing.
I've created a rough jsfiddle that demonstrates this.
I assume this behavior is for optimization purposes, in which case maybe there is some other way to think about my problem.
Thanks for any feedback! Cheers.
The text was updated successfully, but these errors were encountered: