如果项目的布尔属性 value 更改,我可以更改列表中的项目,我的列表会更新。但是,如果我尝试更改字符串属性并返回有效负载,我的列表不会更新。
这在我直接更改项目并将其退回时有效。
case UPDATED_LISTITEM:
let newList = state.list.filter((item) => {
if (item._id !== payload._id) {
return item;
} else {
item.title = payload.title;
item.checked = payload.checked;
return item;
}
});
return {
...state,
list: newList,
};
当我尝试返回有效负载并且只更新“标题”时,这不起作用。如果我更新“已检查”,则状态会正确返回。
case UPDATED_LISTITEM:
return {
...state,
list: state.list.filter((item) => {
if (item._id !== payload._id) {
return item;
} else {
return payload;
}
}),
};
回答1
这里有几个不同的问题。
一是这段代码正在改变 item
,而在使用 Redux 时这是不允许的:
item.title = payload.title;
item.checked = payload.checked;
Redux 需要不可变的更新,这意味着总是制作数据的副本。
另一个是您使用了错误的数组方法。您正在调用 list.filter()
,但您总是返回项目。我认为您想改用 list.map()
。
除此之外,恐怕您正在编写的 Redux 代码的风格已经过时了。看起来您正在“手写”您的减速器、不可变更新和操作类型。
今天,我们使用 Redux Toolkit 和 React-Redux 钩子 API 教授“现代 Redux”,这更易于学习和使用。您正在编写的代码将运行,但它需要编写至少 4 倍的代码,并且会更加混乱。
我强烈建议阅读我们的官方 Redux 文档教程,其中将 Redux 工具包和 React-Redux 钩子作为标准方法进行了介绍:
回答2
不改变状态的版本:
case UPDATED_LISTITEM:
return {
...state,
list: state.list.map((item) => ({
...item, // item must not contain more deeply nested objects!
// Update title and checked from payload
...(
item._id === payload._id ?
{ title: payload.title, checked: payload.checked } : {}
)
}),
};
正如另一个答案所述,使用 redux 工具包更容易。旧方法涉及仔细重构状态,大量使用扩展运算符 (...
)。深度嵌套的对象容易出错。