简短问题:
这两个版本之间有什么区别:
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。
答案 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对象。