如何在GoRouter中向新路由传递BLoC实例?
解决方案:利用GoRouter的
extra参数传递BLoC实例 GoRouter的parameters确实只支持字符串,但它提供了extra参数,可以传递任意类型的对象,刚好满足你在两个路由间共享同一BLoC实例的需求,且无需将BLoC全局暴露。
步骤1:导航时传递BLoC
在发起跳转的页面,使用context.push(或context.go)时通过extra参数传入BLoC实例:
context.push('/favorite-detail', extra: _favoriteBloc);
步骤2:配置路由时接收并提供BLoC
在GoRouter的路由配置中,通过GoRouterState的extra属性取出BLoC,再用BlocProvider.value包裹目标页面:
final GoRouter router = GoRouter( routes: [ // 其他路由配置... GoRoute( path: '/favorite-detail', builder: (context, state) { // 类型转换时建议做非空判断,避免异常 final FavoriteBloc? favoriteBloc = state.extra as? FavoriteBloc; if (favoriteBloc == null) { // 处理参数缺失的情况,比如返回错误页或上一页 return const Scaffold(body: Center(child: Text('参数错误'))); } return BlocProvider.value( value: favoriteBloc, child: const FavoriteDetailPage(), ); }, ), ], );
步骤3:目标页面获取BLoC
FavoriteDetailPage无需修改,依然可以通过Bloc的常规方式获取实例:
// 在页面的build方法或事件处理中 final bloc = context.read<FavoriteBloc>();
备选方案:父子路由共享BLoC
如果两个路由属于同一个父路由的子节点,可以在父路由的builder中提供BlocProvider,这样两个子路由无需传递就能直接获取BLoC:
GoRoute( path: '/favorite-group', builder: (context, state) => BlocProvider.value( value: _favoriteBloc, child: const FavoriteGroupPage(), ), routes: [ GoRoute( path: 'list', builder: (context, state) => const FavoriteListPage(), ), GoRoute( path: 'detail', builder: (context, state) => const FavoriteDetailPage(), ), ], );
这种方式适合两个路由有明确层级关系的场景,同样不会将BLoC全局暴露。
内容的提问来源于stack exchange,提问作者Sunshine
相关产品推荐
相关产品推荐

