我正在学习redux关注redux教程,当我看到todos
todos-github例子时,有些事让我困惑:
Todo.js
const Todo = ({ onClick, completed, text}) => (
<li
onClick={onClick}
style={{
textDecoration: completed ? 'line-through' : 'none'
}}
>
{text}
</li>
)
TodoList.js
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{
todos.map(todo =>
<Todo
key={todo.id}
{...todo} //how does it work?
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
todos
是一个数组,todo
是一个对象:
Todo
项目的道具:
据我所知,Todo
,TodoList
组件函数使用ES6 Destructuring assignment
传递参数,但{...todo}
如何工作?它必须对props
执行某些操作,{}
中的javascript syntax
代表...todo
,因此Varargs
是Todo
到{{1}组件功能?我不知道,任何帮助都会欣赏。
答案 0 :(得分:3)
我们可以使用Babel's REPL检查{...todos}
编译的内容。
正如您在上面的链接中看到的那样(为了清晰起见,我删除了一些内容,但它应该足够简单)创建Todo
组件并将{...todo}
作为prop获取的部分汇编为:
React.createElement(Todo, _extends({ key: todo.id }, todo));
(为简单起见省略onClick
道具 - 如果包括在内,你会看到_extends({ key: todo.id, onClick: /* onClick function */ }, todo)
因此{...todo}
道具实际上导致Babel生成此_extends
函数,该函数定义为:
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
(上面的代码是由Babel生成的一行代码 - 我清理它是为了易读性)
因此,正如您所看到的,将使用解构赋值的prop传递给React组件会导致将destructured对象的所有属性复制到创建时传递给组件的props对象中。此行为不是标准化的ES6功能 - 相反,它是JSX语法的一部分。
总结:如果您的todo
对象如下:
{ completed: false, id: 0, text: "test1" }
将{...todo}
作为道具传递相当于传递
completed={false} id={0} text="test1"
作为道具,你可以这样做,因为它是JSX规范的一个特性。