Ngrx - 减速器无法接收动作

Posted

技术标签:

【中文标题】Ngrx - 减速器无法接收动作【英文标题】:Ngrx - Reducer can't receive action 【发布时间】:2020-08-28 23:52:48 【问题描述】:

我正在尝试在应用初始化时加载一些缓存的详细信息。我正在使用内置的 APP_INITIALIZER 角度提供程序。

在这个提供程序中,我正在运行 AppService 的 init 方法并加载这些缓存信息,调度一些操作。 4 个动作中有 3 个正在优雅地调度,但是当我尝试调度订单详细信息时,reducer 没有得到这个动作,我无法将订单详细信息传输到存储。

但是当我查看 redux chrome 扩展时,我可以看到我的操作正在被调度,但是如果我在 reducer 中记录传入的操作,我看不到我的操作。

奇怪的是,如果我在三秒后使用 setTimeOut 方法运行 loadCachedOrderDetails 方法,setCachedOrderDetails 操作成功调度......

到底发生了什么?如何正确调度 setCachedOrderDetails 操作?

这里是提供者的完整定义

    
      provide: APP_INITIALIZER,
      useFactory: (app: AppService) => () => app.init(),
      deps: [AppService],
      multi: true
    

AppService 初始化方法

  init() 
    const request = this.loadCachedRequest();
    if (request) 
      this.loadCurrentLocation(request);
    
    this.loadCachedBasketItems();
    this.loadCachedOrderDetails();
  

方法


  loadCachedOrderDetails() 
    const details = JSON.parse(localStorage.getItem('orderDetails'));
    if (details) 
      this.store.dispatch(PanelActions.setCachedOrderDetails(details));
    
  

和我注册减速器的面板商店

@NgModule(
  imports: [
    StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
    EffectsModule.forFeature([PanelEffects]),
  ],
  exports: [
    StoreModule,
    EffectsModule
  ]
)
export class PanelStoreModule 

【问题讨论】:

其中一个 JSON.parse 中是否有错误不会抛出但会结束任务的执行? 实际上,我还记录了详细信息 这很奇怪。如果你改变调度的顺序,有什么改变吗? 不,它仍然没有发送相同的操作 但是如果你将它包装在一个 setTimeout 中它就可以工作,所以它不是拼写错误或错误的类。如果你把console.log(action) 放在reducer 中,任何reducer 都会注销这个action? 【参考方案1】:

如果您使用EffectsModule.forFeature,则表示此模块不是主要模块,并且您的应用已经初始化,并且您的模块很可能在稍后需要应用时被延迟加载或初始化。

因此,您不能依赖任何 INIT 触发器。因为它们可以在您设置功能并准备好监听操作之前发出。

但您可以简单地使用模块的构造函数来调度所需的操作。

@NgModule(
  imports: [
    StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
    EffectsModule.forFeature([PanelEffects]),
  ],
  exports: [
    StoreModule,
    EffectsModule,
  ]
)
export class PanelStoreModule 
  constructor(app: AppService) 
    app.init();
  

或者干脆将效果和reducer移动到forRoot部分。

【讨论】:

我希望我有数百个赞成票来投票这个答案,你节省了十个小时的调试时间。我刚刚创建了新的面板服务并将面板相关代码移动到那里,并且没有任何延迟,它工作得很好。因为正如您所提到的,效果和存储延迟加载以及其他操作都有效,因为它们位于根寄存器中。

以上是关于Ngrx - 减速器无法接收动作的主要内容,如果未能解决你的问题,请参考以下文章

只有一个减速器的NGRX的多个存储

NGRX 效果看不到商店中的完整状态

有没有办法为ngrx中的已调度操作触发“基本”操作?

相同 NgRx 功能模块的独立实例

ngrx - 更新项目列表中的单个项目

如何使用 react-redux 调试 action.type 问题,单动作类型单减速器,但无法识别类型