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 - 减速器无法接收动作的主要内容,如果未能解决你的问题,请参考以下文章