Flutter用go_router+riverpod时出现unknown route name报错求助
Flutter中使用go_router与flutter_riverpod配置路由时出现"unknown route name: /auth/:uid"错误
错误信息
The following assertion was thrown building
DefaultSelectionStyle:
unknown route name: /auth/:uid
'package:go_router/src/configuration.dart':
Failed assertion: line 243 pos 12:
'_nameToPath.containsKey(name)'
相关代码
main.dart
void main() { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) .then((_) async { await Firebase.initializeApp(); await FirebaseAppCheck.instance .activate(androidProvider: AndroidProvider.playIntegrity); runApp( const ProviderScope( child: MyApp(), ), ); }); FlutterError.demangleStackTrace = (StackTrace stack) { if (stack is stack_trace.Trace) return stack.vmTrace; if (stack is stack_trace.Chain) return stack.toTrace().vmTrace; return stack; }; } class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return MaterialApp.router( debugShowCheckedModeBanner: false, title: 'DiscountLo', theme: AppTheme.theme, locale: ref.watch(languageNotifierProvider), localizationsDelegates: { AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate }, supportedLocales: [Locale("en"), Locale("hi")], routerDelegate: ref.watch(routeProvider).routerDelegate, routeInformationParser: ref.watch(routeProvider).routeInformationParser, routeInformationProvider: ref.watch(routeProvider).routeInformationProvider, ); } }
router.dart
final routeProvider = Provider<GoRouter>( (ref) { return GoRouter( routes: [ GoRoute( name: "home", path: RouteNameConstants.home, pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage( child: const HomeView(), ), ), GoRoute( name: "splash", path: RouteNameConstants.splash, pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage( child: const SplashScreen(), ), ), GoRoute( name: "onboard", path: RouteNameConstants.onboarding, pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage( child: const OnboardingView(), ), ), GoRoute( name: "error", path: RouteNameConstants.error, pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage( child: ErrorPage(text: state.pathParameters['text']!), ), ), GoRoute( name: "auth", path: RouteNameConstants.authState, pageBuilder: (BuildContext context, GoRouterState state) { return MaterialPage( child: AuthChanges(uid: state.pathParameters['uid']!), ); }, ), GoRoute( name: "filter", path: RouteNameConstants.filter, pageBuilder: (BuildContext context, GoRouterState state) { return MaterialPage( child: FilterView( index: double.tryParse(state.pathParameters['index']!)!.toInt(), category: state.pathParameters['category']!, ), ); }, ), ], redirect: (context, state) { final loginState = ref.watch(authStateChangeProvider); if (loginState.isLoading) { return RouteNameConstants.splash; } else if (loginState.hasError) { return state.namedLocation( RouteNameConstants.error, pathParameters: { "text": loginState.error.toString(), }, ); } else if (loginState.value != null) { return state.namedLocation(RouteNameConstants.authState, pathParameters: {"uid": loginState.value!.uid}); } else { return RouteNameConstants.onboarding; } }, ); }, );
路由常量类
class RouteNameConstants { static const String home = '/'; static const String splash = '/splash'; static const String onboarding = '/onboarding'; static const String authState = '/auth/:uid'; static const String error = '/error/:text'; static const String filter = '/filter'; }
解决方案
问题核心:state.namedLocation()方法需要传入路由的name属性值,而非路由的path路径。你的代码中错误地传入了path常量(如RouteNameConstants.authState),导致go_router无法匹配到对应的路由name。
修复步骤
- 新增路由name常量,避免硬编码字符串:
class RouteNameConstants { static const String home = '/'; static const String splash = '/splash'; static const String onboarding = '/onboarding'; static const String authState = '/auth/:uid'; static const String error = '/error/:text'; static const String filter = '/filter'; // 新增路由name常量 static const String homeName = "home"; static const String splashName = "splash"; static const String onboardName = "onboard"; static const String authName = "auth"; static const String errorName = "error"; static const String filterName = "filter"; }
- 修正redirect中的
state.namedLocation()参数:
redirect: (context, state) { final loginState = ref.watch(authStateChangeProvider); if (loginState.isLoading) { return RouteNameConstants.splash; } else if (loginState.hasError) { return state.namedLocation( RouteNameConstants.errorName, // 替换为路由name常量 pathParameters: { "text": loginState.error.toString(), }, ); } else if (loginState.value != null) { return state.namedLocation( RouteNameConstants.authName, // 替换为路由name常量 pathParameters: {"uid": loginState.value!.uid}); } else { return RouteNameConstants.onboarding; } },
- (可选)规范路由配置,将GoRoute的name属性替换为常量:
GoRoute( name: RouteNameConstants.authName, // 使用常量替代硬编码 path: RouteNameConstants.authState, pageBuilder: (BuildContext context, GoRouterState state) { return MaterialPage( child: AuthChanges(uid: state.pathParameters['uid']!), ); }, ),
内容的提问来源于stack exchange,提问作者abhi jain
相关产品推荐
相关产品推荐

