React.js - 当从父组件展开.map的结果时,this.props.children是一个对象

12

我遇到了一些奇怪的行为,当我从父组件中使用 .map() 并展开结果时,this.props.children 会转换为一个对象。

例子:

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 (
    // ...
  );
}

奇怪的是,当我省略.map()并直接传递元素时,它们出现在this.props.children中,就像预期的数组一样:

render() {
  return (
    <DropdownMenu
      label={'Some label'}
      onChange={() => {}}
    >
      <DropdownMenu_listItem item={{...}} />
      <DropdownMenu_listItem item={{...}} />
    </DropdownMenu>
  );
}

// DropdownMenu.js

render() {
  console.log(this.props.children); // [{…}, {…}]

  return (
    // ...
  );
}
任何关于为什么会发生这种情况的见解都将不胜感激。

这个决定背后有什么原因吗? - Celestriel
请查看这个答案,它会有所帮助。https://dev59.com/M1kS5IYBdhLWcg3wHTNy - Suresh Ponnukalai
3个回答

7
不是因为地图的原因而获得子对象,而是因为您在项中使用了展开运算符。
<DropdownMenu
          label={'Some label'}
          onChange={() => {}}
        >
          {...items} {/*spread operator here */}
</DropdownMenu>

现在,使用{...items}将一个数组映射后,由于你用{}包装了扩展运算符的结果,它变成了一个对象。如果你写{items},也是可以的。
 <DropdownMenu
      label={'Some label'}
      onChange={() => {}}
    >
      {items}
 </DropdownMenu>

但是OP提到,如果他删除map功能,那么他会得到数组。根据您的答案,在这两种情况下,他都应该得到对象。这正确吗? - Suresh Ponnukalai
2
在第二种情况下,他手动添加了<DropdownMenu_listItem item={{...}} /> <DropdownMenu_listItem item={{...}} />作为子元素,并没有使用扩展运算符。 - Shubham Khatri

7

{...items}是在DropdownMenu.js中作为子项传递的。

它作为this.props.children可用。

this.props.children可以是数组或对象,取决于您如何呈现子元素。

在您的情况下

<DropdownMenu
      label={'Some label'}
      onChange={() => {}}
    >
      {...items}
</DropdownMenu>

items 是一个数组。正如我们所知,

array is also type of object in javascript

with key equal to element's index and value is element itself

{...items} : 这将作为一个对象传递,键为元素索引,值等于数组元素。

要解决您的问题,您应该在不使用展开运算符的情况下传递它。

{items} : 这将被传递为一个数组。

<DropdownMenu
      label={'Some label'}
      onChange={() => {}}
    >
      {items}
</DropdownMenu>

我之前使用的是{...children},但它没有起作用,所以我改用了{this.props.children},结果非常好! - Sajid2405

4
在我的情况下,将其传递为属性将会起作用。
之前。
function Foo(props) {
    return <Bar> {...props} </Bar>
}

之后

function Foo(props) {
    return <Bar {...props}> </Bar>
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接