在 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;
})
所以我试图在我的状态下更改数组中对象的 属性。
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;
})