[英]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_router
的context
!!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.