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

使用go_router与flutter_bloc时出现No GoRouter found in context异常求助

解决BlocListener中调用context.goNamed出现"No GoRouter found in context"异常

问题根源在于:BlocListener的context属于MaterialApp.router的上层上下文,而GoRouter是通过MaterialApp.router注入到其子树上下文里的,上层上下文无法获取到GoRouter实例,因此触发断言失败。

解决方案

  • 方案一:将BlocListener移到MaterialApp.router内部
    把BlocListener作为MaterialApp.router的子组件,让listener的上下文能访问到GoRouter:

    Widget build(BuildContext context) {
      return BlocProvider<AuthenticationBloc>(
        create: (context) => AuthenticationBloc()..add(AppStarted()),
        child: MaterialApp.router(
          title: 'Flutter Demo',
          routeInformationProvider: _router.routeInformationProvider,
          routeInformationParser: _router.routeInformationParser,
          routerDelegate: _router.routerDelegate,
          theme: ThemeData(primarySwatch: Colors.blue),
          child: BlocListener<AuthenticationBloc, AuthenticationState>(
            listener: (context, state) {
              if (state is AuthenticationUnauthenticated) {
                context.goNamed(LoginPage.routeName);
              }
              if (state is AuthenticationAuthenticated) {
                context.goNamed(NavigationBarContainer.routeName);
              }
            },
            child: const SplashScreen(), // 这里替换为你的初始页面组件
          ),
        ),
      );
    }
    
  • 方案二:直接使用GoRouter实例跳转
    利用已有的_router实例直接跳转,无需依赖上下文:

    listener: (context, state) {
      if (state is AuthenticationUnauthenticated) {
        _router.goNamed(LoginPage.routeName);
      }
      if (state is AuthenticationAuthenticated) {
        _router.goNamed(NavigationBarContainer.routeName);
      }
    },
    
  • 方案三:用Builder获取子树上下文
    通过Builder组件拿到MaterialApp.router下层的上下文,以此访问GoRouter:

    child: BlocListener<AuthenticationBloc, AuthenticationState>(
      listener: (context, state) {
        Builder(
          builder: (routerContext) {
            if (state is AuthenticationUnauthenticated) {
              routerContext.goNamed(LoginPage.routeName);
            }
            if (state is AuthenticationAuthenticated) {
              routerContext.goNamed(NavigationBarContainer.routeName);
            }
            return const SizedBox.shrink();
          },
        );
      },
      child: MaterialApp.router(...),
    ),
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:25:16