Ngrx/store动作重复执行问题排查求助
NGRX/Entity中Dispatch动作被重复处理两次的问题
我正在用NgRx/Entity开发一个部门(Department)与区域(Area)关联管理的Angular应用,遇到了一个奇怪的问题:
- 手动dispatch任意动作(包括其他feature模块的动作)时,该动作会被Reducer处理两次
- Effects内部派发的动作处理正常(之前Effects里用
mergeMap时也会重复,换成exhaustMap后恢复正常)
已经做了以下排查:
- 确认dispatch方法仅被调用一次,没有处于循环或重复订阅逻辑中
- 所有Selector都是通过模板的
asyncpipe使用,没有手动订阅Store的情况 - 单独运行部门模块(不关联区域逻辑)时,没有出现动作重复处理的问题,因此推测问题出在部门与区域关联的Reducer或Selector实现中
附上相关代码片段:
Reducer 代码(部门与区域关联部分)
import { EntityState, createEntityAdapter } from '@ngrx/entity'; import { DepartmentActions, AreaActions } from '../actions'; export interface DepartmentsState extends EntityState<Department> { selectedDepartmentId: string | null; areasByDepartment: Record<string, string[]>; // 部门关联的区域ID映射 } export const departmentsAdapter = createEntityAdapter<Department>(); export const initialState: DepartmentsState = departmentsAdapter.getInitialState({ selectedDepartmentId: null, areasByDepartment: {}, }); export function departmentsReducer( state = initialState, action: DepartmentActions | AreaActions ): DepartmentsState { switch (action.type) { case DepartmentActions.AddDepartmentSuccess.type: return departmentsAdapter.addOne(action.payload, { ...state, areasByDepartment: { ...state.areasByDepartment, [action.payload.id]: [], }, }); case AreaActions.AssignAreaToDepartment.type: return { ...state, areasByDepartment: { ...state.areasByDepartment, [action.payload.departmentId]: [ ...state.areasByDepartment[action.payload.departmentId], action.payload.areaId, ], }, }; // 其他case逻辑 default: return state; } }
Selector 代码(部门与区域关联部分)
import { createSelector, createFeatureSelector } from '@ngrx/store'; import { DepartmentsState, departmentsAdapter } from './departments.reducer'; const selectDepartmentsState = createFeatureSelector<DepartmentsState>('departments'); export const { selectAll: selectAllDepartments, selectEntities: selectDepartmentEntities, } = departmentsAdapter.getSelectors(selectDepartmentsState); export const selectAreasByDepartment = createSelector( selectDepartmentsState, (state) => state.areasByDepartment ); export const selectDepartmentWithAreas = createSelector( selectDepartmentEntities, selectAreasByDepartment, (departmentEntities, areasByDepartment) => { return Object.values(departmentEntities).map(department => ({ ...department, areas: areasByDepartment[department.id] || [], })); } );
同时附上动作重复处理的日志截图:
内容的提问来源于stack exchange,提问作者Federico Xella
相关产品推荐
相关产品推荐

