簡體   English   中英

go_router 和 flutter_bloc:未處理的異常:在上下文中找不到 GoRouter

[英]go_router and flutter_bloc: Unhandled Exception: No GoRouter found in context

我用 BlocProvider / BlocListener 包裝了 MaterialApp

我得到一個錯誤

"Unhandled Exception: 'package:go_router/src/router.dart': Failed assertion: line 280 pos 12: 'inherited != null': No GoRouter found in context" from the Listener callback
Widget build(BuildContext context) {
    return BlocProvider<AuthenticationBloc>(
      create: (context) => AuthenticationBloc()..add(AppStarted()),
      child: BlocListener<AuthenticationBloc, AuthenticationState>(
        listener: (context, state) {
          if (state is AuthenticationUnauthenticated) {
            context.goNamed(LoginPage.routeName);
          }
          if (state is AuthenticationAuthenticated) {
            context.goNamed(NavigationBarContainer.routeName);
          }
        },
        child: MaterialApp.router(
            title: 'Flutter Demo',
            routeInformationProvider: _router.routeInformationProvider,
            routeInformationParser: _router.routeInformationParser,
            routerDelegate: _router.routerDelegate,
            theme: ThemeData(
              primarySwatch: Colors.blue,
            )),
      ),
    );
  }

您正在嘗試使用小部件樹中比插入 go_router 更高的context進行導航。

我不知道你的GoRouter() routerConfig 在哪里,以及當你使用RouterDelegate時從哪里調用它,(也許你不需要使用委托?)但是你需要直接調用你的GoRouter配置,然后導航從那個。

所以你需要改變:

context.goNamed(LoginPage.routeName)

routerConfig.goNamed(LoginPage.routeName)

對我來說,您可以看到我將routerConfig傳遞給MaterialApp.router ,並且我還使用routerConfig.go(HOME)MaterialApp上方直接導航:

    ref.watch(authStatusServiceProvider).whenData((authStatus) {
      switch (authStatus) {
        case AuthenticationStatusEnum.authenticated:
          routerConfig.go(HOME);
          break;
        case AuthenticationStatusEnum.unauthenticated:
          routerConfig.go(LOGGED_OUT_HOME);
          break;
        default:
          routerConfig.go(LOGGED_OUT_HOME);
          break;
      }
    });

    return MaterialApp.router(
      theme: lightTheme,
      debugShowCheckedModeBanner: false,
      darkTheme: darkTheme,
      routerConfig: routerConfig,
    );
  }

所有功勞都歸功於 Github 上的 darshankawar

發生這種情況是因為您在初始化之前使用了go_routercontext !!

Widget build(BuildContext context) {
    return BlocProvider<AuthenticationBloc>(
      create: (context) => AuthenticationBloc()..add(AppStarted()),
      child: BlocListener<AuthenticationBloc, AuthenticationState>(
        listener: (context, state) {
          if (state is AuthenticationUnauthenticated) {
            context.goNamed(LoginPage.routeName);              // 👈 Go router is not initilaized yet
          }
          if (state is AuthenticationAuthenticated) {
            context.goNamed(NavigationBarContainer.routeName); // 👈 Go router is not initilaized yet
          }
        },
        child: MaterialApp.router(
            routeInformationProvider: _router.routeInformationProvider,
            routeInformationParser: _router.routeInformationParser,
            routerDelegate: _router.routerDelegate,            // 👈 Your router is initialized here
      ),
    );
  }

對以下內容進行更改:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider<AuthenticationBloc>(
            create: (context) => AuthenticationBloc()..add(AppStarted()), 👈 Specify only the BlocProvider here
          ),
        ],
        child: MaterialApp(
            theme: customTheme(context),
            debugShowCheckedModeBanner: false,
            routeInformationProvider: _router.routeInformationProvider,
            routeInformationParser: _router.routeInformationParser,
            routerConfig: router,
  }

然后嘗試在router內部導航,例如:

final GoRouter router = GoRouter(routes: [
  GoRoute(
      path: "/",
      builder: (context, state) {
        return BlocBuilder<AuthCubit, AuthState>(
          buildWhen: (oldState, newState) {
            return oldState is AuthInitialState;
           },
          builder: (context, state) {
            if (state is AuthenticationUnauthenticated) {
              // return const LoginPage();                         // alternative way
               context.goNamed(LoginPage.routeName);               👈 Use conditional routing using context here 
            } else if (state is NavigationBarContainer.routeName) {
              // return SignIn();                                 // alternative way
                context.goNamed(NavigationBarContainer.routeName); 👈 Use conditional routing using context here 
            } else {
              return const Scaffold();
            }
          },
        );
      }),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM