Angular 17独立组件中配置多NgRx Reducer的问题排查
NgRx状态切片访问undefined的解决方法(Angular17独立组件)
你的问题根源是同时混用了NgRx的模块式配置(StoreModule.forRoot)和独立式配置(provideStore/provideState),且provideState用法错误,导致状态切片未正确注册,最终选择器访问属性时返回undefined。
错误配置的核心问题
- Angular17独立组件模式下,无需使用
StoreModule.forRoot(这是NgRx模块式的配置方式) provideStore与provideState的组合用法错误,不能用合并后的根reducer去注册单个状态切片
正确配置方案(二选一)
方案一:使用provideStore结合合并后的根reducer
import { ApplicationConfig } from '@angular/core'; import { provideRouter, withComponentInputBinding } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; import { provideHttpClient, withFetch } from '@angular/common/http'; import { combineReducers, provideStore } from '@ngrx/store'; import { provideEffects } from '@ngrx/effects'; import { loginReducer } from './states/auth.reducer'; import { LoginEffects } from './states/auth.effects'; import { adminLoginReducer } from './states/adminAuth.reducer'; import { AdminLoginEffects } from './states/adminAuth.effects'; // 合并两个reducer作为根reducer const rootReducer = combineReducers({ login: loginReducer, adminLogin: adminLoginReducer }); export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes, withComponentInputBinding()), provideClientHydration(), provideHttpClient(withFetch()), // 注册根reducer provideStore(rootReducer), // 注册effects provideEffects([LoginEffects, AdminLoginEffects]) ] };
方案二:使用provideState逐个注册状态切片(更推荐,模块化)
import { ApplicationConfig } from '@angular/core'; import { provideRouter, withComponentInputBinding } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; import { provideHttpClient, withFetch } from '@angular/common/http'; import { provideStore, provideState } from '@ngrx/store'; import { provideEffects } from '@ngrx/effects'; import { loginReducer } from './states/auth.reducer'; import { LoginEffects } from './states/auth.effects'; import { adminLoginReducer } from './states/adminAuth.reducer'; import { AdminLoginEffects } from './states/adminAuth.effects'; export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes, withComponentInputBinding()), provideClientHydration(), provideHttpClient(withFetch()), // 初始化Store provideStore(), // 分别注册两个状态切片 provideState({ name: 'login', reducer: loginReducer }), provideState({ name: 'adminLogin', reducer: adminLoginReducer }), // 注册effects provideEffects([LoginEffects, AdminLoginEffects]) ] };
配套选择器的正确写法
确保选择器中使用的切片名称与配置中注册的名称完全一致:
// auth.selectors.ts import { createFeatureSelector, createSelector } from '@ngrx/store'; import { LoginState } from './auth.reducer'; // 获取login切片的根选择器 export const selectLoginState = createFeatureSelector<LoginState>('login'); // 获取具体属性的选择器 export const selectLoginToken = createSelector( selectLoginState, (state) => state.token ); export const selectLoginIsLoading = createSelector( selectLoginState, (state) => state.isLoading );
// adminAuth.selectors.ts import { createFeatureSelector, createSelector } from '@ngrx/store'; import { AdminLoginState } from './adminAuth.reducer'; export const selectAdminLoginState = createFeatureSelector<AdminLoginState>('adminLogin'); export const selectAdmin = createSelector( selectAdminLoginState, (state) => state.admin );
内容的提问来源于stack exchange,提问作者Nafeesath Musfira Badriya
相关产品推荐
相关产品推荐

