为什么他们没有在Redux教程中直接在map()中更改属性?
这里是一个 redux noob。
在这部分的redux 教程中,特别是为什么他们没有做这样的事情
case 'todos/todoToggled': {
return {
...state,
todos: state.todos.map(todo => {
if (todo.id === action.payload.todoId) {
todo.completed = !todo.completed
}
return todo
}
)
}
据我所知map(),Mozilla 文档中没有引用任何副作用
map() 方法创建一个新数组,其中填充了对调用数组中的每个元素调用提供的函数的结果。
他们为什么要做这个额外的步骤?
// We've found the todo that has to change. Return a copy:
return {
...todo,
// Flip the completed flag
completed: !todo.completed
}
会影响功能吗?或者他们只是想保持一致?
回答
据我所知
map()没有任何副作用
它可能有副作用,map 方法创建一个新数组的事实并不意味着它不会有任何副作用。例如:
const arr = [{x: 1}, {x: 2}, {x: 3}];
const newA = arr.map(obj => {
obj.x += 1; // changes the objects in `arr`
return obj;
});
console.log(newA); // new array (objects are still references to original ones)
console.log(arr); // Also changed!
map 函数会传递一个对每个对象的引用,这意味着当您更改 时obj,它也会在原始数组中更改它。因此,当您执行以下操作时:
todo.completed = !todo.completed
您正在更改todo数组中的对象,这会导致您直接更改状态。
与上面不同的是,呈现的代码:
{
...todo,
completed: !todo.completed
}
不会更改todo对象引用,而是从它获取所有(可枚举自己的)键并将其放入一个新对象中,这也会覆盖completed键以保存否定(即:相反)completed布尔值。