首页 > 解决方案 > 在 redux 工具包状态中更改数组中的特定元素

问题描述

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

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
 })

它给了我一个错误,说我的列表未定义:

未处理的拒绝 (TypeError):newList[_id] 未定义

我不知道为什么,因为我在向我的数组中添加一个新对象时做了一些非常相似的事情,而且效果很好。

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

标签: javascriptreactjsreduxreact-reduxredux-toolkit

解决方案


数组还是对象?索引还是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我不认为它是。我认为您已经混淆了语法并在这里假设您有一个object键控_id而不是array.

解决方案

你有一个不匹配,所以你可以改变任何一个来匹配另一个。

如果state.listarray

.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;
})

推荐阅读