我正在尝试设计具有相当复杂状态的 webapp,其中许多单个操作应该触发跨多个组件的多个更改和更新,包括从外部端点异步获取和显示数据。
我正在构建一个混合的 cytoscape.js / redux 应用程序,用于使用图形对蛋白质相互作用进行建模。
我的 Redux 存储需要保存图形的表示(节点和边对象的集合),以及可由用户设置的众多过滤参数(即仅显示包含特定值的节点等)。
当前的实现使用 React.js 来管理所有状态,随着应用程序的增长,它变得非常单一,难以推理和调试。
以前从未使用过 Redux,在尝试从概念上设计新实现时,我有点挣扎。具体来说,我有以下问题/疑虑:
Cytoscape.js 是一个独立的组件,因为它直接操作 DOM。它期望状态(特别是节点和边集合)具有某种形状,这是嵌套的并且有点难以处理。由于对任何节点或边缘对象的每次更新都应该在 cytoscape 中以图形方式反映,我应该在 Redux 存储中镜像它期望的形状,还是应该在每次更新时转换它?如果是这样,那么什么地方是一个好地方呢?mapStateToProps 还是在减速器里面?
某些事件,例如选择节点和/或边,会在整个应用程序中产生多种副作用(从服务器异步获取数据,从选择中提取其他数据并进行转换/聚合,其中一些是派生的,一些是它来自外部 api 调用)。我在思考如何处理这些变化时遇到了麻烦。更具体地说,假设触发了 SELECTION_CHANGE 操作。它应该包含选定的对象,还是只包含它们的 ID?我猜从性能角度来看,ID 的负担会更小。更重要的是,我应该如何处理 SELECTION_CHANGE 操作所需的级联更新?单个 SELECTION_CHANGE 操作应触发 UI 和状态树的多个部分的更改。这意味着在不同的减速器上触发多个动作。
用户需要能够根据任意谓词过滤和操作图。更具体地说,他应该能够永久删除\添加节点和边,并将视图限制在图形的特定子集上。换句话说,一些更改是永久性的(删除\添加或以其他方式编辑图形),而其他更改仅与显示的内容相关(例如,仅显示表达水平高于某个阈值的节点等)。我应该在我的状态树中保留一个单独的、“过滤”的图形副本,还是应该针对过滤参数的每次更改动态计算它?和以前一样,如果是这样,哪里是执行这些过滤操作的好地方:mapStateToProps、reducers 或其他我没有想到的地方?
我希望这些高层次和抽象的问题足以描述我想要实现的目标,如果不是,我很乐意详细说明。