ngxs - ngxs 状态运算符插入或替换数组中的项目(upsert)
问题描述
我正在尝试用现有的 ngxs 状态运算符替换或插入一个数组项(upsert)。我目前正在使用以下 iif 语句。有没有更简单的方法来做到这一点?
setState(
patch({
contractList: iif<Contract[]>(
contractList=>
contractList.some(
contract =>
contract.id === contractId
),
updateItem<Contract>(
contract =>
contract.id === contractId,
patch(loadedContract)
),
insertItem<Contract>(loadedContract)
)
})
)
解决方案
国家运营商存在,但这并不意味着您被迫使用它们,对吧。有一个秘诀叫做Immutability Helpers。它将在 1-2 周内发布到主站点。
如果我们谈论的是状态运算符,那么可以创建自定义运算符,这是某种分解:
function insertOrUpdateContract(id: string, loadedContract?: Contract) {
return iif<Contract[]>(
contracts => contracts.some(contract => contract.id === id),
updateItem(contract => contract.id === id, patch(loadedContract)),
insertItem(loadedContract)
);
}
因此,您的操作处理程序中的代码将更少,并且更具自我描述性:
ctx.setState(
patch({ contractList: insertOrUpdateContract(contractId, loadedContract) })
);
否则,您可以使用immer
库或其他首选的东西,这样可以节省更多代码:
import { produce } from 'immer';
const state = produce(ctx.getState(), draft => {
const index = draft.contractList.findIndex(contract => contract.id === contractId);
// It exists then let's update
if (index > -1) {
draft.contractList[index] = loadedContract;
} else {
draft.contractList.push(loadedContract);
}
});
ctx.setState(state);
肯定immer
是该项目的附加包,但它非常轻量级。它提供了更多的声明方式来进行这种不可变的更新。选择最适合您的!
当涉及到如此复杂的状态更新时,我会停止使用一些不变性助手。
推荐阅读
- nsview - 使用 XCode 在 MacOS 应用程序中放置在 NSScrollView 内的 NSView 不显示滚动条
- json - 在颤动中发送带有json正文的GET请求
- javascript - 按 className 滚动到作为元素子项的子项的段落的视图 - 纯 JS
- python - 根据列值的计数过滤 CSV 行
- colors - 在地图地理熊猫的色标中设置起点
- apache-kafka - Kafka Streams:什么时候调用 StateRestoreListener?
- python - TypeVar('T') 和 Any 之间的区别
- node.js - 带有 Typescript 错误的玩笑:超时 - 在 jest.setTimeout.Timeout 指定的 5000 毫秒超时内未调用异步回调
- python - 无法在 pycharm 中安装 xml.etree.elementtree
- flutter - flutter-web - 当应用程序通过浏览器的地址栏以不同的路由启动时,避免 initialRoute 启动?