You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NgRx Effect未触发求助:分发动作后Effect不执行

排查NgRx中addRawOrder绑定的Effect未执行问题

我近期在项目中配置了NgRx,为OrderModel模型实现了Action、Reducer与Effect。但分发绑定该Effect的addRawOrder动作时,Effect始终未执行,附上相关代码请求排查:

OrderModel

export interface OrderModel {
  orderNumber?: number;
  destination?: LatLngLiteral;
  source?: LatLngLiteral;
  accepted?: boolean;
  sourceAddressText?: string;
  destinationAddressText?: string;
}

Actions

export const addRawOrder = createAction('[Order] Add new orders', props<{orders: OrderModel[]}>());
export const addOrder = createAction('[Order] Add new orders', props<{orders: OrderModel[]}>());
export const setSelectedOrder = createAction('[Order] Set selected order', props<{order: OrderModel}>());
export const setSelectedOrderAccepted = createAction('[Order] Set selected order accepted', props<{order: OrderModel}>());

Reducer代码

import {addOrder, addRawOrder, setSelectedOrder, setSelectedOrderAccepted} from "./order-actions";

export interface OrderState {
  orders: OrderModel[];
  selectedOrder: OrderModel | null;
}


const initialState: OrderState = {orders: [], selectedOrder: null};

export const orderReducers = createReducer(initialState,
  on(addRawOrder, (state, {orders}) => ({...state})),
  on(addOrder, (state, {orders}) => ({...state, orders: [...state.orders, ...orders]})),
  on(setSelectedOrder, (state, {order}) => ({...state, selectedOrder: order})),
  on(setSelectedOrderAccepted, (state, {order}) => ({...state, selectedOrder: {...order, accepted: true}}))
);

Effect代码

@Injectable()
export class OrderEffects {

  constructor(private actions$: Actions, private neshanService: NeshanService) {
  }

  getPosts$ = createEffect(() =>
    this.actions$.pipe(
      ofType(addRawOrder),
      switchMap((action) => {
        return this.neshanService.reverseGeocodingSourceDestinationOder(action.orders);
      }),
      map(orders => addOrder({orders: orders}))
    )
  )
}

app.module.ts中的配置

StoreModule.forRoot({orders: orderReducers}),
EffectsModule.forRoot([OrderEffects]),

问题根源

最核心的错误是**addRawOrder和addOrder两个Action的类型字符串完全重复**:都是[Order] Add new orders。

NgRx依赖Action的类型字符串来识别不同动作,重复的类型会导致:

  • 分发addRawOrder时,NgRx无法准确区分该动作与addOrder
  • Effect监听的addRawOrder动作被干扰,无法触发对应的处理流

此外还有两个次要问题:

  • Reducer中addRawOrder的处理逻辑未修改状态,仅返回原状态拷贝(不影响Effect执行,但属于无效逻辑)
  • Effect中的方法名getPosts$与功能不符,语义化不足

解决方案

  1. 修改Action类型字符串,保证唯一性
    将两个Action的类型字符串改为不同值,比如:

    export const addRawOrder = createAction('[Order] Add raw orders', props<{orders: OrderModel[]}>());
    export const addOrder = createAction('[Order] Add processed orders', props<{orders: OrderModel[]}>());
    

    这样NgRx能准确识别addRawOrder,Effect就能正常触发。

  2. 优化Reducer中addRawOrder的逻辑(可选)
    如果不需要在Reducer中处理addRawOrder,直接移除对应的on配置;若需保留,确保逻辑合理:

    // 无需处理则删除该行
    on(addRawOrder, (state) => ({...state})),
    
  3. 修正Effect方法名(可选)
    改为更贴合功能的名称:

    processRawOrders$ = createEffect(() =>
      this.actions$.pipe(
        ofType(addRawOrder),
        switchMap((action) => {
          return this.neshanService.reverseGeocodingSourceDestinationOder(action.orders);
        }),
        map(orders => addOrder({orders: orders}))
      )
    )
    

内容的提问来源于stack exchange,提问作者Pouya Kermanshahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:40:29