Reputation: 377
I am having some strange behaviour where this.props.children
is converting to an object when I spread the result of a .map()
from the parent.
example:
const items = [
{ id: 1, name: "Name1" },
{ id: 2, name: "Name2" }
].map((item) => {
return (
<DropdownMenu_listItem key={item.id} item={item} />
);
});
render() {
return (
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
{...items}
</DropdownMenu>
);
}
// DropdownMenu.js
render() {
console.log(this.props.children); // {0: {…}, 1: {…}}
return (
// ...
);
}
The weird part is that when I omit the .map()
and pass the elements directly, they appear in this.props.children
as an array like expected:
render() {
return (
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
<DropdownMenu_listItem item={{...}} />
<DropdownMenu_listItem item={{...}} />
</DropdownMenu>
);
}
// DropdownMenu.js
render() {
console.log(this.props.children); // [{…}, {…}]
return (
// ...
);
}
Any insight into why this is happening would be greatly appreciated.
Upvotes: 12
Views: 26407
Reputation: 846
In my case passing as attr will worked
before
function Foo(props) {
return <Bar> {...props} </Bar>
}
after
function Foo(props) {
return <Bar {...props}> </Bar>
}
Upvotes: 4
Reputation: 15292
{...items}
is passed as childrens in DropdownMenu.js
.
Its available as a this.props.children
this.props.children
can be array or object depend on how you rendering the children elements.
in your case
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
{...items}
</DropdownMenu>
items is an array. As we know
array is also type of object in javascript
with key equal to element's index and value is element itself
{...items}
: this will passed as a object with key as a element index and value equal to array element.
To fix your problem, you should passed it without using spread operator.
{items}
: this will passed as an array.
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
{items}
</DropdownMenu>
Upvotes: 7
Reputation: 281736
Its not because of map that you get children as object, but because you use spread operator for the items in
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
{...items} {/*spread operator here */}
</DropdownMenu>
Now that after map items is an array using {...items }
makes it an object since you wrap your result of spread operator with {}
, If you write {items}
, that will be fine
<DropdownMenu
label={'Some label'}
onChange={() => {}}
>
{items}
</DropdownMenu>
Upvotes: 7