子模块用StoreModule.forFeature,根模块用forRoot致状态树多一层如何解决?
问题分析与解决方案
错误原因
- 必须调用
StoreModule.forRoot():NGRX的StoreModule.forRoot()是全局Store的初始化入口,它会提供ReducerManager等核心依赖服务,根模块(AppModule)必须调用一次,否则会触发找不到ReducerManager的注入错误。 - 嵌套的
auth节点:你在AuthModule中使用StoreModule.forFeature('auth', reducers)时,reducers本身是一个包含auth键的对象(比如{ auth: authReducer }),这相当于把整个reducers对象挂载到了名为auth的feature节点下,最终状态树就形成了auth -> auth -> ...的嵌套结构。
解决方案
方式一:调整Feature模块的Reducer传入形式(推荐)
如果Auth模块仅负责管理auth状态,直接传入单个reducer函数给StoreModule.forFeature,而非带auth键的对象:
修改AuthModule中的代码:
// 假设原reducers定义为 { auth: authReducer },改为直接传入authReducer @NgModule({ imports: [ // ...其他模块 StoreModule.forFeature('auth', authReducer) ], // ...其他配置 }) export class AuthModule {}
修改后,根状态树的auth节点会直接对应你的登录状态,不会出现嵌套。
方式二:在根模块统一注册根Reducer
如果你的reducers是多feature的组合对象,可在StoreModule.forRoot()中统一注册根reducer,Feature模块不再使用forFeature:
- 修改AppModule:
@NgModule({ imports: [ // ...其他模块 StoreModule.forRoot({ auth: authReducer }), EffectsModule.forRoot([AuthEffects]), StoreDevtoolsModule.instrument() ], // ...其他配置 }) export class AppModule {}
- 修改AuthModule,移除
StoreModule.forFeature:
@NgModule({ imports: [ CommonModule, RouterModule.forRoot(ROUTES), AngularFireAuthModule, provideFirebaseApp(() => initializeApp(environment.firebase)), provideAuth(() => getAuth()), SharedModule.forRoot() ], providers: [{ provide: FIREBASE_OPTIONS, useValue: environment.firebase }] }) export class AuthModule {}
内容的提问来源于stack exchange,提问作者Ian Tunbridge
相关产品推荐
相关产品推荐

