反应休息参数语法与扩展语法

时间:2017-08-02 15:35:08

标签: javascript reactjs ecmascript-6 components

简短问题

这两个版本之间有什么区别:

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充当rest参数语法表示传递给组件的其余props。

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

但是,...rest作为参数传递:

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

表示扩展语法。在这里,我们似乎也只是使用组件函数定义中的相同道具克隆子元素。

但是组件A如何工作?

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

我们是如何从...rest转到rest的?

最后,为什么当用括号C

括起来时它不起作用

我已经阅读了关于React和ES6文档的文档,但是没有很好的文档可以使用它们together使用React API。

2 个答案:

答案 0 :(得分:5)

{ ...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键下的属性,因此最后一个案例会失败,如您所见。

答案 1 :(得分:4)

您的函数声明实际上使用了destructuring以及rest参数。 在你的例子中

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并将其分配给单独的变量,并使用spread运算符获取其余的对象属性并解析为具有这些属性的对象。

那么你的3个案件会发生什么?

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属性的新对象,该属性具有分配给它的rest对象。