NGRX AppState动态节点子集改造后reducer注册方案咨询
解决方案
核心思路是创建一个高阶父reducer处理字典结构的路由转发,完全复用现有单个NodesState的reducer逻辑,不需要修改原有reducer的代码。
步骤1:编写Nodes根reducer包装器
import { ActionReducer, Action } from '@ngrx/store'; import { nodesReducer } from './nodes.reducer'; import { NodesState } from './nodes.state'; // 约束节点相关Action必须携带containerId interface NodesRelatedAction extends Action { containerId?: string; } export const nodesRootReducer: ActionReducer<Record<string, NodesState>, NodesRelatedAction> = ( state = {}, // 初始状态为空字典 action: NodesRelatedAction ) => { // 过滤非节点相关、未携带containerId的action if (!action.containerId || !action.type.startsWith('[Nodes]')) { return state; } // 取出对应容器的当前状态,首次访问时传入undefined触发子reducer的默认初始化逻辑 const targetContainerState = state[action.containerId]; // 完全复用原有单容器reducer计算新状态 const updatedContainerState = nodesReducer(targetContainerState, action); // 状态无变更时直接返回原对象,避免不必要的状态更新触发 if (updatedContainerState === targetContainerState) { return state; } // 返回更新后的字典结构 return { ...state, [action.containerId]: updatedContainerState }; };
步骤2:替换Store注册逻辑
直接把原来注册的nodesReducer替换为上面写的nodesRootReducer即可:
StoreModule.forRoot(<ActionReducerMap<AppState, Action>>{ auth: <ActionReducer<AuthState, Action>>authReducer, settings: <ActionReducer<SettingsState, Action>>settingsReducer, nodes: nodesRootReducer, // ... })
可选优化项
- 新增
[Nodes] 清空容器类的action,匹配到该action时直接从state字典中删除对应containerId的属性,在容器组件销毁时触发,避免内存泄漏 - 如果有遗留的单容器业务代码,可以新增兼容选择器,默认返回指定默认容器的状态,无需修改旧业务逻辑
- 给所有节点相关action统一添加带
containerId的类型约束,在编译阶段避免漏传标识的问题
内容的提问来源于stack exchange,提问作者Dmitry Gusarov
相关产品推荐
相关产品推荐

