反应休息参数语法与传播语法

Posted

技术标签:

【中文标题】反应休息参数语法与传播语法【英文标题】:React rest parameters syntax vs spread syntax 【发布时间】:2018-01-09 22:26:15 【问题描述】:

简短的问题

这两个版本有什么区别:

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

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

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

这个版本不行:

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

更详细的问题

...休息与休息

在组件函数定义中声明的...rest充当休息参数语法表示传递给组件的其余道具。

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

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

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

表示展开语法。在这里,我们似乎也只是简单地从组件函数定义中克隆了具有相同道具的子元素。

但是组件 A 是如何工作的呢?

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

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

最后,为什么用像组件C这样的括号括起来却不起作用

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

【问题讨论】:

这能回答你的问题吗? Spread Syntax vs Rest Parameter in ES2015 / ES6 【参考方案1】:

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

【讨论】:

【参考方案2】:

你的函数声明实际上使用了解构和其他参数。 在你的例子中

const A = ( children, ...rest ) =&gt; ...

函数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 从对象中挑选出来并分配给单独的变量,扩展运算符用于获取对象的其余属性并解析为具有这些属性的对象。

那么在你的 3 个案例中会发生什么?

const A = ( children, ...rest ) =&gt; React.cloneElement(children, rest); 这个将对象传递给 React.cloneElement,所有对象属性都没有 children 属性。

const B = ( children, ...rest ) =&gt; React.cloneElement(children, ...rest); 这个等效于第一个-它将对象属性传播到对象。这个操作其实是多余的。

const C = ( children, ...rest ) =&gt; React.cloneElement(children, rest ); 这个创建了具有 rest 属性的新对象,该属性已分配了休息对象。

【讨论】:

以上是关于反应休息参数语法与传播语法的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript ES6 - 这是扩展语法还是休息语法?

扩展语法无法按预期与对象数组一起工作

reactjs中的传播语法“...this.props”感觉很奇怪

Array.from() 与传播语法

在反应js中添加动态参数的语法[重复]

JavaScript 传播语法与 jQuery $.extend - ByRef 和 ByVal