基于页面中的示例:https://redux.js.org/basics/usage-with-reakct
我们有以下项目:
const Todo = ({ onClick, completed, text }) => (
<li
onClick={onClick}
style={{
textDecoration: completed ? 'line-through' : 'none'
}}
>
{text}
</li>
)
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
另外,我们有:
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map((todo, index) => (
<Todo key={index} {...todo} onClick={() => onTodoClick(index)} />
))}
</ul>
)
有人可以告诉我上述代码上的{... todo}是什么?
我知道...运营商是一种差异语法,可以用作[...但是,在上面的示例中,TODO项目不是一个数组,似乎它会生成一个对象。因此,对我来说,它看起来{... todo}等于{todo}。
另外,在组件上分配了哪些属性?
...
也可以用于传播对象,而不仅仅是数组。例如,
// Using rest syntax here
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
// Using spread here
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
在上述情况下,todos
是包含键completed
和text
的对象数组。而不是手动通过这样的道具 -
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map((todo, index) => (
<Todo key={index} completed={todo.completed} text={todo.text} onClick={() => onTodoClick(index)} />
))}
</ul>
)
我们使用差异语法添加键值对作为道具。您可以将其视为句法糖。
... todo用于将道具传递给Todo组件。在Todo Proptypes中,您可以看到有两个可变类型的道具。所以...操作员扩散(通过)将其传播到todo组件的道具
const obj = {a: 1, b: 2, c: 3};
<MyComponent {...obj} />
与<MyComponent a={1} b={2} c={3} />
相同。因此,您使用spread
操作员...
从对象或数组中取出元素。
外部反应,如果const test={a: 1, b:2 }
,则const x = {test} //es6 feature
与const x = {test: test}
相似。因此,这与const x = {test: {a: 1, b:2}}
在哪里, <MyComponent {obj} />
在 MyComponent
内部造成了反应错误,可以用于访问传递的 obj
的道具的名称。空无一人。因此错误。
function MyComponent(props) {
// What is props.? to access obj
}
所以,您使用一个名称的道具,
<MyComponent x={obj} />
function MyComponent(props) {
// props.x has obj
// props.x = obj
console.log(props.x);
return <div />
}
,但是,传播操作员自动将props名称与对象键和值一起作为对象的值,如本答案开头所示。
正如您在问题中所说的那样,const newTodos = [...todos, newItem]
创建了一个新数组,其中旧的Todos从todos
中散布并添加了额外的newItem
。如果您没有传播todos
,它将创建newTodos = [[todo1, todo2],newItem]
。