Flutter使用Auto Route实现条件路由失效问题求助
问题原因分析
你的代码存在几个关键问题导致isLoggedIn为true时仍跳转到登录页:
- 状态更新未触发UI重建:在BlocConsumer的listener中更新
isLoggedIn后,没有调用setState(),导致_buildMaterialApp方法无法获取到最新的isLoggedIn值,始终使用初始的false。 - 重复触发验证请求:在BlocConsumer的builder中每次都调用
context.read<AuthCubit>().isValid(),会导致组件重建时重复发起验证请求,且初始阶段isLoggedIn还未更新就已经创建了nextScreen。 - nextScreen未动态更新:AnimatedSplashScreen的
nextScreen是在_buildMaterialApp中创建的,当isLoggedIn变化时,由于没有触发UI重建,这个nextScreen不会重新生成,仍然使用初始的LoginRoute。
修复方案
方案一:修复现有代码逻辑
- 移走build中的验证调用:在
initState中触发验证,避免重复调用
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { context.read<AuthCubit>().isValid(); }); }
- 更新状态时触发UI重建:在listener中更新
isLoggedIn时调用setState
listener: (context, state) { if (state is TokenIsValid) { setState(() { isLoggedIn = state.isValid; }); } },
- 移除build中的验证调用:删除BlocConsumer builder里的
context.read<AuthCubit>().isValid();语句
方案二:使用Auto Route守卫(更规范的方式)
Auto Route推荐使用路由守卫(AutoRouteGuard)处理条件路由,这比手动判断initialRoutes更可靠:
- 创建AuthGuard类
class AuthGuard extends AutoRouteGuard { @override void onNavigation(NavigationResolver resolver, StackRouter router) { final authState = resolver.context.read<AuthCubit>().state; if (authState is TokenIsValid && authState.isValid) { // 已登录,允许进入目标页面 resolver.next(); } else { // 未登录,跳转到登录页 router.push(const LoginRoute()); } } }
- 在路由配置中添加守卫
修改app_router.dart,给需要登录的路由添加守卫,并设置HomeRoute为初始路由:
@MaterialAutoRouter( initialRoute: HomeRoute.name, routes: [ AutoRoute(page: LoginRoute), AutoRoute(page: HomeRoute, guards: [AuthGuard]), ], ) class AppRouter extends _$AppRouter {}
- 简化主页面路由配置
移除initialRoutes的手动判断,直接使用Auto Route的默认代理:
MaterialApp _buildMaterialApp(BuildContext context, AuthState state) { print(isLoggedIn); return MaterialApp( debugShowCheckedModeBanner: false, title: 'Gider', builder: BotToastInit(), theme: CustomTheme.primaryTheme, localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, home: AnimatedSplashScreen( splash: const SplashPage(), animationDuration: const Duration(seconds: 2), nextScreen: MaterialApp.router( debugShowCheckedModeBanner: false, theme: CustomTheme.primaryTheme, routeInformationParser: _appRouter.defaultRouteParser(includePrefixMatches: true), routerDelegate: _appRouter.delegate(), ), ), ); }
- 调整AuthCubit的初始状态
确保AuthCubit的初始状态为未验证状态(比如AuthInitial),避免守卫误判。
内容的提问来源于stack exchange,提问作者Selim Hür
相关产品推荐
相关产品推荐

