You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AutoRoute与Riverpod实现导航守卫时遇到报错问题

问题分析与解决方案

核心错误点

  1. guards参数类型错误:你在AutoRoute的guards数组里传入了AuthGuard类本身,但auto_route要求传入**AutoRouteGuard的实例**,而非类型。
  2. 依赖注入问题:AuthGuard依赖Riverpod的Ref,无法在AppRouter的routes配置中直接实例化,因为AppRouter初始化时还未进入ProviderScope上下文。
  3. onNavigation逻辑无效:onNavigation是void类型方法,你内部的maybeMap返回bool不会产生任何导航控制效果,必须通过NavigationResolver和StackRouter来执行实际的导航逻辑。

修正步骤

1. 修复AuthGuard的导航控制逻辑

修改onNavigation方法,根据登录状态执行允许导航或跳转登录页的操作:

class AuthGuard extends AutoRouteGuard {
  final Ref _ref;
  AuthGuard(this._ref);

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) async {
    // 监听登录状态(同步状态直接watch,异步状态需用future)
    final authState = _ref.watch(authNotifierProvider);
    
    authState.maybeMap(
      authenticated: (_) {
        // 已登录,允许访问目标页面
        resolver.resolve(true);
      },
      orElse: () {
        // 未登录,跳转到登录页,登录成功后重新尝试导航
        router.push(SignInRoute(onResult: (isSuccess) {
          isSuccess ? resolver.resolve(true) : resolver.resolve(false);
        }));
      },
    );
  }
}

2. 修改AppRouter,通过构造函数注入AuthGuard实例

让AppRouter接收外部传入的AuthGuard实例,避免在routes配置中直接依赖:

class AppRouter extends _$AppRouter {
  final AuthGuard authGuard;

  AppRouter(this.authGuard);

  @override
  List<AutoRoute> get routes => [
        AutoRoute(
          page: SplashRoute.page,
          initial: true,
        ),
        // 传入已初始化的authGuard实例
        AutoRoute(page: StarredRepoRoute.page, guards: [authGuard]),
        AutoRoute(page: SignInRoute.page),
        AutoRoute(page: AuthorizationRoute.page),
      ];

  // 修正isInitialRoute为getter(原方法写法不符合auto_route要求)
  @override
  bool get isInitialRoute => false;
}

3. 在main函数中正确初始化AppRouter

通过Riverpod容器获取AuthGuard实例,再传入AppRouter:

void main() {
  runApp(
    ProviderScope(
      child: Builder(
        builder: (context) {
          // 从Provider容器中读取AuthGuard实例
          final authGuard = ProviderScope.containerOf(context).read(authGuardProvider);
          return MaterialApp.router(
            routerDelegate: AutoRouterDelegate(
              AppRouter(authGuard),
              navigatorObservers: () => [AutoRouteObserver()],
            ),
            routeInformationParser: AppRouter(authGuard).defaultRouteParser(),
          );
        },
      ),
    ),
  );
}

额外注意事项

  • 如果authNotifierProvider是AsyncNotifier,需使用_ref.watch(authNotifierProvider.future)来等待状态加载完成,避免处理loading状态时的异常。
  • 登录页的onResult回调需要在登录成功后返回true,通知守卫允许继续导航。

内容的提问来源于stack exchange,提问作者Akhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:37:34