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

use*_*977 3 javascript components ecmascript-6 reactjs

问题简而言之:

这两个版本有什么区别:

const A = ({ children, ...rest }) => React.cloneElement(children, rest);
Run Code Online (Sandbox Code Playgroud)

VS

const B = ({ children, ...rest }) => React.cloneElement(children, {...rest});
Run Code Online (Sandbox Code Playgroud)

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

此版本不起作用:

const C = ({ children, ...rest }) => React.cloneElement(children, { rest });
Run Code Online (Sandbox Code Playgroud)

问题更详细:

......休息与休息

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

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

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

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

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

但是组件A如何工作?

const A = ({ children, ...rest }) => React.cloneElement(children, rest);
Run Code Online (Sandbox Code Playgroud)

我们是怎么...rest来的rest

最后,为什么当用C组件括起来时它不起作用

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

Ros*_*mon 5

{ ...rest }有效地做了原始rest对象的浅表副本.它保持原始形状,但它在内存中是一个不同的参考点.

rest也显然保持相同的形状,因为它是同一个对象.你只是传递参考.

{ rest }不起作用,因为它创建一个新对象并将旧rest对象指定为键的值"rest".


作为上述3种情况的示例,请说您的原始props形状如下:

{
  children: <div>,
  label: 'Foo',
  value: 5
};
Run Code Online (Sandbox Code Playgroud)

创建一个对象并通过构造函数({ children, ...rest })传递它之后,children已经分离rest,留下了以下对象:

{
  label: 'Foo',
  value: 5
};
Run Code Online (Sandbox Code Playgroud)

使用时{ ...rest },对象保持相同的形状:

{
  label: 'Foo',
  value: 5
};
Run Code Online (Sandbox Code Playgroud)

使用时rest,对象不仅保持相同的形状,而且字面上保持相同的对象:

{
  label: 'Foo',
  value: 5
};
Run Code Online (Sandbox Code Playgroud)

有了{ rest },你指派老rest"rest"关键:

{
  rest: {
    label: 'Foo',
    value: 5
  },
};
Run Code Online (Sandbox Code Playgroud)

由于组件需要第一个形状,并且不期望rest键下的属性,因此最后一个案例会失败,如您所见.


luk*_*eli 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"}
Run Code Online (Sandbox Code Playgroud)

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

那么你的 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其属性已分配有剩余对象。