📜  react redux 如何在 reducer 中更改对象值 - Javascript (1)

📅  最后修改于: 2023-12-03 15:34:39.063000             🧑  作者: Mango

如何在 Redux reducer 中更改对象值

在 Redux 中,state 是不可变的,即一旦创建,就不能被直接修改。而修改 state 只能通过创建新的 state 对象来实现。在 reducer 中更改对象值需要遵循以下步骤:

  1. 复制对象
  2. 修改副本
  3. 返回新的对象
复制对象

首先,需要使用对象扩展运算符(...)或Object.assign()方法以创建state对象的副本。

对象扩展运算符

使用对象扩展运算符可以通过将新属性附加到现有对象来创建已知对象的副本。例如:

const newState = {
  ...state,
  todos: [
    ...state.todos,
    {
      id: 3,
      text: action.text,
      completed: false,
    }
  ]
}

以上代码会使用对象扩展运算符来创建state副本,然后将todos数组复制,最后向数组中添加一个新的todo项。

Object.assign()方法

您还可以使用 Object.assign(target, ...sources) 方法来将一个或多个对象的属性复制到另一个对象中。例如:

const newState = Object.assign({}, state, {
  todos: [
    ...state.todos,
    {
      id: 3,
      text: action.text,
      completed: false,
    }
  ]
})

以上代码会创建一个新的空对象,复制 state 对象和一个新的 todo 项(使用对象扩展运算符)。然后将这些对象的属性分配给一个新的对象。

修改副本

现在您拥有了 state 对象的副本,可以安全地修改这个副本。例如:

const newState = {
  ...state,
  todo: state.todos.map(todo => {
    if (todo.id === action.id) {
      return Object.assign({}, todo, {
        completed: !todo.completed
      })
    }
    return todo
  })
}

以上代码使用对象扩展运算符复制 state 副本和新的 todo 项,并使用 map() 方法遍历复制的 todo,如果找到匹配的 todo,就在副本中将其 completed 属性取反。最后,返回state副本,其中新todo替换了原始数组中的旧todo。

返回新的对象

最后,必须返回新的对象以代替原始的 state 对象。以下是完整的代码片段:

function todos(state = [], action) {
  switch (action.type) {
    case 'TOGGLE_TODO':
      const newState = {
        ...state,
        todos: state.todos.map(todo => {
          if (todo.id === action.id) {
            return Object.assign({}, todo, {
              completed: !todo.completed
            })
          }
          return todo
        })
      }
      return newState
    default:
      return state
  }
}
结论

在 Redux reducer 中更改对象值需要注意以下几个细节:

  1. 不要直接修改原始的 state 对象,而是创建一个 state 的副本。
  2. 在副本中做任何更改,不会影响原始的 state 对象。
  3. 必须返回新的对象,以便 Redux 知道什么已经更改了。

总而言之,这就是在 Redux reducer 中更新对象值的正确方法。如果您需要对其进行更多深入的了解,可以在 Redux 官方文档中阅读更多。