为什么他们不直接在 Redux 教程的 map() 中更改 属性?

Why they didn't change property directly in map() in Redux tutorial?

这里是 redux 新手。

在 redux 教程中 this part particularly 为什么他们不做那样的事情

        case 'todos/todoToggled': {
            return {
                ...state,
                todos: state.todos.map(todo => {
                    if (todo.id === action.payload.todoId) {
                        todo.completed = !todo.completed
                    }
                    return todo
                }
                )
            }

据我所知 map() 没有引用 Mozilla docs

的任何副作用

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

为什么他们做了这个额外的步骤?

          // We've found the todo that has to change. Return a copy:
          return {
            ...todo,
            // Flip the completed flag
            completed: !todo.completed
          }

会影响功能吗?或者他们只是想保持一致?

As far as I know map() doesn't have any side effects

可以有副作用,事实上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 布尔值。