GoRouter报错:'Null'不是String的子类型,路由刷新后失效
go-router刷新页面报'Null' is not subtype of String问题解决
问题场景
使用go-router做路由管理,首次跳转product页面能正常传参,但刷新页面后触发类型错误:'Null' is not subtype of String,即使传入任意参数,跳转后刷新仍会报错。
问题代码
跳转触发代码
onTap: () { context.pushNamed("product", params: {'id':"dsadklaskld"}); },
路由配置代码
final GoRouter _router = GoRouter( debugLogDiagnostics: true, initialLocation: '/', routes: [ GoRoute( path: '/', builder: (BuildContext context, GoRouterState state) { return const MainPage(); }, ), GoRoute( path: '/product/:id', name: 'product', builder: (context, state){ final id = state.params['id']!; return DetailsView(id:id); }, ), GoRoute( path: '/homepage', builder: (BuildContext context, GoRouterState state) { return const HomePage(); }, ), ], );
目标页面DetailsView代码
class DetailsView extends StatefulWidget { final String id; /// Constructs a [DetailsScreen] const DetailsView({super.key, required this.id}); @override State<DetailsView> createState() => _DetailsViewState(); } class _DetailsViewState extends State<DetailsView> { // ... late String id = widget.id; }
问题原因
核心问题在于强制解包运算符!的滥用:虽然路由路径/product/:id定义了必填参数id,但在web端刷新页面时,go-router可能因URL解析、路由恢复的偶发问题导致state.params['id']返回null,此时!会直接触发类型转换错误。
解决方案
1. 移除强制解包,增加参数校验
修改路由配置中的builder方法,先校验参数是否存在,避免空值强制转换:
GoRoute( path: '/product/:id', name: 'product', builder: (context, state){ final id = state.params['id']; // 参数缺失时跳转到错误页或首页 if (id == null) { return Scaffold( body: Center(child: Text('商品ID参数缺失')), ); } return DetailsView(id:id); }, ),
2. 配置web端URL策略(仅web应用)
在main函数中设置URL路径策略,确保web端刷新时参数能正确解析:
import 'package:go_router/go_router.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; void main() { // 设置path策略(替代默认的hash策略) GoRouter.setUrlPathStrategy(UrlPathStrategy.path); runApp(const MyApp()); }
3. 升级go-router到最新稳定版
部分旧版本的go-router存在刷新时参数丢失的bug,执行以下命令升级依赖:
flutter pub upgrade go_router
4. 可选:使用类型安全的参数传递
通过extra参数传递类型安全的数据,避免路径参数解析问题(适合复杂参数场景):
- 跳转时:
onTap: () { context.pushNamed("product", extra: "dsadklaskld"); },
- 路由配置:
GoRoute( path: '/product', name: 'product', builder: (context, state){ final id = state.extra as String?; if (id == null) { return const MainPage(); } return DetailsView(id:id); }, ),
内容的提问来源于stack exchange,提问作者Mohammed Malek
相关产品推荐
相关产品推荐

