React中的剩余参数语法 vs 展开语法

5

简要问题:

这两个版本有什么区别:

const A = ({ children, ...rest }) => React.cloneElement(children, rest);

vs

const B = ({ children, ...rest }) => React.cloneElement(children, {...rest});

两个版本似乎以相同的方式工作。

这个版本不起作用:

const C = ({ children, ...rest }) => React.cloneElement(children, { rest });

更详细的问题:

...rest vs rest

...rest 在组件函数定义中声明时,作为剩余参数语法表示传递给组件的其余props。

例如:const B = ({ children, ...rest })

然而,当作为参数传递的...rest

例如:React.cloneElement(children, {...rest})

它代表展开语法。在这里,似乎我们也只是从组件函数定义中克隆具有相同props的子元素。

但组件A是如何工作的?

const A = ({ children, ...rest }) => React.cloneElement(children, rest);

我们是如何从...restrest的呢?

最后,为什么用括号包围组件C时它就不起作用了?

我已经阅读了React和ES6的文档,但是没有很好的文档介绍如何使用React APIs 结合 ES6。


这个回答解决了你的问题吗?ES2015/ES6中的展开语法与剩余参数有什么区别? - Henke
2个回答

6

{ ...rest }实际上是对原始rest对象进行浅拷贝。它保留了原始形状,但在内存中是一个不同的引用点。

rest也显然保持相同的形状,因为它是相同的对象。您只是传递了引用。

{ rest }不起作用,因为它创建了一个新对象,并将旧的rest对象分配给键"rest"的值。


以上述3种情况为例,假设您的原始props形状如下:

{
  children: <div>,
  label: 'Foo',
  value: 5
};

创建一个对象并通过构造函数传递它后({ children, ...rest }),children已经从rest中分离出来,留下了以下的对象:
{
  label: 'Foo',
  value: 5
};

使用{ ...rest },对象保持相同的形状:
{
  label: 'Foo',
  value: 5
};

使用rest,对象不仅保持相同的形状,而且确实是相同的对象:

{
  label: 'Foo',
  value: 5
};

使用 { rest },你将会把旧的 rest 赋值给 "rest" 键:

{
  rest: {
    label: 'Foo',
    value: 5
  },
};

由于该组件期望第一个形状,并且不期望在rest键下出现属性,因此正如您所观察到的那样,最后一种情况会失败。


5

您的函数声明实际上使用了解构和剩余参数。在您的示例中:

const A = ({ children, ...rest }) => ...

函数A接受一个对象作为参数,并将其解构为单独的变量,例如:

const A = ({ a, ...rest }) => { console.log('a', a, 'rest', rest) }
A({a: 1, b: 2, c: 'hello world'})
// a 1 rest Object {b: 2, c: "hello world"}

如您所见,上面的变量a是从对象中选取并分配给单独的变量,并使用展开运算符获取其余对象属性并解析为具有这些属性的对象。

那么在您的三种情况下会发生什么?

const A = ({ children, ...rest }) => React.cloneElement(children, rest); 此方法将所有对象属性传递给React.cloneElement,但不包括children属性。

const B = ({ children, ...rest }) => React.cloneElement(children, {...rest}); 此方法等同于第一个方法-它将对象属性展开到对象中。实际上,这个操作是多余的。

const C = ({ children, ...rest }) => React.cloneElement(children, { rest }); 此方法创建一个新对象,其中rest属性具有分配给它的剩余对象。


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