Angular + NgRx:页面刷新时等待user加载完成再导航
解决NgRx Auth状态初始化前路由闪烁问题
页面刷新时Auth状态初始化是异步操作,当前路由默认直接跳转至welcome页面,等Store中user状态更新后才匹配books路由,导致页面短暂闪烁。以下是具体解决方案:
1. 区分Auth状态的“未初始化”与“已登录/未登录”
先修改Auth的State结构,添加标志跟踪Auth是否初始化完成,同时明确user的状态含义:undefined表示未初始化、null表示未登录、用户对象表示已登录:
// auth.reducer.ts export interface AuthState { user: User | null | undefined; authLoaded: boolean; // 新增:标记Auth状态是否已初始化完成 } const initialState: AuthState = { user: undefined, authLoaded: false, }; export const authReducer = createReducer( initialState, on(AuthActions.login, (state, { user }) => ({ ...state, user, authLoaded: true, })), on(AuthActions.logout, (state) => ({ ...state, user: null, authLoaded: true, })) );
同时更新Auth状态监听逻辑,未登录时也派发logout动作,确保Auth状态标记为已初始化:
stateChanged = onAuthStateChanged(getAuth(), (user) => { if (user) { this.store.dispatch(AuthActions.login({ user })); } else { this.store.dispatch(AuthActions.logout()); } });
2. 修改路由逻辑,等待Auth初始化完成后再导航
调整app.routes.ts,让默认路由不再直接跳转welcome,而是等待Auth状态初始化完成后,根据user值决定最终导航目标:
export const APP_ROUTES: Routes = [ { path: '', component: ShellComponent, children: [ // 初始空路径:等待Auth初始化完成后再匹配后续路由 { path: '', pathMatch: 'full', canMatch: [() => inject(Store).select(selectAuthLoaded).pipe( filter(loaded => loaded), map(() => true), first() )], redirectTo: '', }, // 已登录用户:直接跳转至books页面 { path: '', pathMatch: 'full', canMatch: [() => inject(Store).select(selectUser).pipe( map(user => !!user), first() )], redirectTo: 'books' }, // 未登录用户:跳转至welcome页面 { path: '', pathMatch: 'full', canMatch: [() => inject(Store).select(selectUser).pipe( map(user => user === null), first() )], redirectTo: 'welcome' }, // Welcome页面路由 { path: 'welcome', loadChildren: async () => (await import('@welcome/feat/welcome')).WELCOME_ROUTES, }, // 已登录用户的books路由 { path: '', canMatch: [() => inject(Store).select(selectUser).pipe( map(user => !!user), first() )], providers: [provideState(booksFeature),provideEffects(booksEffects)], children: [ { path: 'books', loadChildren: async () => (await import('@books/feat/books')).BOOKS_ROUTES, }, ], }, // 404路由 { path: '**', redirectTo: 'welcome', }, ], }, ];
3. 可选:添加初始化加载状态
如果想在Auth初始化期间显示加载动画,可在ShellComponent中监听authLoaded状态,控制内容显示:
// shell.component.ts authLoaded$ = this.store.select(selectAuthLoaded); constructor(private store: Store) {}
<!-- shell.component.html --> <div *ngIf="authLoaded$ | async; else loading"> <router-outlet></router-outlet> </div> <ng-template #loading> <div class="loading-spinner">加载中...</div> </ng-template>
这样页面刷新时会先显示加载状态,等Auth初始化完成后直接导航到对应页面,不会出现welcome页面的短暂闪烁。
内容的提问来源于stack exchange,提问作者pax
相关产品推荐
相关产品推荐

