reactjs - 为什么当我在 redux 中这个 reducer 中的状态发生变化时我的状态没有重新渲染
问题描述
这符合逻辑,但我的组件没有重新渲染
case CONSTANTS.DELETE_CARD:
const newStateInit = state.map((list) => {
if (list.id === action.payload.listID) {
let delcardIndex = list.cards.findIndex((card) => {
return card.id === action.payload.cardID;
});
list.cards.splice(delcardIndex, 1);
}
return list;
});
localStorage.setItem("todo-list", JSON.stringify(newStateInit));
return [...newStateInit];
解决方案
I suspect the issue lies in the fact that even though the state is a new array reference, the specific list element is not, and is in fact, being mutated with the splice
(recall that splice
operates on the array in place). Spreading newStateInit
into a new array is superfluous since Array.prototype.map
already returns a new array reference.
When updating state you typically need to also shallow copy any nested state that is being updated. Map the existing state into newStateInit
, and while mapping previous list
element objects when the list.id
matches the payload, shallow copy the list
element and use Array.prototype.filter
to return a new cards
array where the current card.id
doesn't match the id you are trying to remove.
case CONSTANTS.DELETE_CARD:
const { cardID } = action.payload;
const newStateInit = state.map((list) => {
if (list.id === action.payload.listID) {
return {
...list,
cards: list.cards.filter(card => card.id !== cardID),
};
}
return list;
});
localStorage.setItem("todo-list", JSON.stringify(newStateInit));
return newStateInit;
推荐阅读
- sql - 在 shell 脚本中连接到 sqlplus 并使用单独的密码运行 sql 脚本
- yii2 - Yii2 的 Matchheight 扩展不起作用
- javascript - 我可以用更好的方式写这个条件吗?
- discord.js - 如何禁止和踢掉公会成员
- javascript - 我无法将请求正文添加到我的输出中
- php - 如何在 Symfony 4 中将数据库连接“localhost”更改为“127.0.0.1”?
- python - 在 python pandas 中加速 read_csv
- c++ - Knight 的巡回递归只填满了 60 个方格
- java - 为什么 XSD 模式和 WSDL 模式之间存在差异?
- http - HTTP 反向 shell 比 TCP 反向 shell 有什么好处?