NgRx如何实现reducer通用复用 解决多selector对应状态冲突问题
NgRx通用reducer复用解决方案
问题核心原因
你当前给不同的状态切片绑定了同一个reducer函数实例,导致所有切片都会响应所有匹配的action,自然所有selector拿到的状态会同步更新。要实现逻辑复用同时规避该问题,核心是实现高阶reducer工厂,根据配置生成独立的、仅响应对应action的reducer实例,无需重复编写15份逻辑代码。
实现方案
第一步:编写通用reducer工厂
该工厂接收配置参数,返回独立的reducer实例,通用逻辑只需要写一次:
// 通用reducer工厂入参配置 const createDataImportReducer = (config) => { const { allowedActionTypes, initialState = defaultDataImportState } = config; // 返回独立的reducer实例 return (state = initialState, action) => { // 仅响应配置指定的action类型,不匹配的action直接返回原状态 if (!allowedActionTypes.includes(action.type)) return state; // 所有导入场景通用的状态更新逻辑,仅需要编写一次 console.log(action.type, action.payload); return { ...state, // 这里写通用的状态处理逻辑,比如加载状态、结果存储、错误处理等 loading: true, error: null, ...action.payload }; }; };
第二步:生成各场景独立reducer
每个导入场景仅需要一行代码生成专属reducer,无需重复编写逻辑:
// 分别生成两类导入的专属reducer const dataImportAllocationClassesReducer = createDataImportReducer({ allowedActionTypes: [fromActions.IMPORT_ALLOCATION_CLASSES] }); const dataImportFundsReducer = createDataImportReducer({ allowedActionTypes: [fromActions.IMPORT_FUNDS] }); // 剩余13个导入场景仅需要按以上格式新增一行配置即可,无需新增逻辑代码 export const dataImportReducer: ActionReducerMap<DataImportStoreState> = { dataImportAllocationClasses: dataImportAllocationClassesReducer, dataImportFunds: dataImportFundsReducer, };
额外优化(可选)
如果selector也存在大量重复代码,可以同步编写selector工厂复用逻辑:
// selector工厂,传入切片key即可生成对应selector const createDataImportSelector = (sliceKey) => { return createSelector( getDataImportSoreState, (state) => state[sliceKey] ); }; // 生成各场景selector,一行一个无需重复编写逻辑 export const getDataImportAllocationClassesState = createDataImportSelector('dataImportAllocationClasses'); export const getDataImportFundsState = createDataImportSelector('dataImportFunds');
内容的提问来源于stack exchange,提问作者Ricardo Saracino
相关产品推荐
相关产品推荐

