在 redux 工具包状态中更改数组中的特定元素

Alter a specific element in an array inside redux toolkit state

所以我试图在我的状态下更改数组中对象的 属性。

export const changeStatus = createAsyncThunk('changeStatus', async (arg) => {
    const todo = arg
    const response = await axios.put(`${URL}/${todo._id}`, { ...todo, done: !todo.done })
    return response.data
})

这是有效的,它改变了我在数据库中的待办事项,但是当我尝试在我的状态中改变它时,像这样:

.addCase(changeStatus.fulfilled, (state, action) => {
             const {_id, done} = action.payload
             let newList = state.list
             newList[_id].done = done
 })

它给我错误提示我的列表未定义:

Unhandled Rejection (TypeError): newList[_id] is undefined

我不明白为什么,因为我在向我的数组添加新对象时做了一些与它非常相似的事情并且它工作正常。

.addCase(addTodos.fulfilled, (state, action) => {
            let newList = state.list
            newList.unshift(action.payload)
        })

数组还是对象?索引或 ID?

let newList = state.list
newList.unshift(action.payload)

这里说 state.list 是一个 array。它还表示待办事项的 _id 与其在该数组中的索引之间没有关系,因为我们在该列表的开头添加新的待办事项,从而更改每个现有条目的索引。

考虑到这一点,希望您现在可以看到问题所在:

const {_id, done} = action.payload
let newList = state.list
newList[_id].done = done

访问 newList[_id] 仅当 _id 是该项目在列表中的索引时才有效。我不认为是。我认为你混淆了语法并假设你有一个由 _id 键控的 object 而不是 array.

解决方案

你有一个不匹配的地方,所以你可以更改其中一个以匹配另一个。

如果 state.list 是一个 array:

.addCase(changeStatus.fulfilled, (state, action) => {
  const {_id, done} = action.payload
  // find this todo in the list
  const todo = state.list.find(t => t._id === _id);
  // update that todo
  todo.done = done;
  // note: .find() might return undefined, so you may want to handle that
})
.addCase(addTodos.fulfilled, (state, action) => {
  // prepend to list
  state.list.unshift(action.payload);
})

如果 state.list 是键控 object:

.addCase(changeStatus.fulfilled, (state, action) => {
  const {_id, done} = action.payload
  // update status for this key
  state.list[_id].done = done;
})
.addCase(addTodos.fulfilled, (state, action) => {
  const todo = action.payload;
  // set the todo at this key
  state.list[todo._id] = todo;
})