Flutter使用Bloc Cubit跨页传值时第二页列表为空问题
问题根因
出现跨页面数据为空的核心问题是实例化了两个完全独立的FavoritesCubit对象,两个对象的内存状态完全隔离:
- 第一个FavoritesCubit在Main.dart的MultiBlocProvider中初始化,绑定在HomeView的上层上下文,首页所有收藏增删操作修改的都是这个实例的内部数据,日志能读到正确长度也是因为操作的是这个实例。
- 第二个FavoritesCubit在FavoriteView.dart的build方法中通过
BlocProvider(create: (context) => FavoritesCubit()..getAllFavorites())重新创建,这个新实例的收藏列表初始为空,路由跳转后页面监听的是这个新实例的状态,自然读不到之前在首页存入的数据。
另外现有Cubit写法存在额外隐患:将收藏列表单独作为Cubit类属性存储,没有完全纳入State状态管理,后续状态更新时容易出现列表引用不同步、UI不刷新的问题。
修复方案
- 移除FavoriteView中重复创建FavoritesCubit的逻辑
收藏页不需要新建Cubit实例,直接使用上层已经初始化好的全局FavoritesCubit即可。如果是普通Navigator.push跳转,可通过BlocProvider.value传递已有实例,避免上下文找不到Bloc的问题。
修改后的FavoriteView核心代码:
如果是直接push路由跳转,传参示例:@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Bloc Example"), ), body: Builder( builder: (context) { // 进入页面触发一次列表刷新,读取的是同一个Cubit实例的数据 context.read<FavoritesCubit>().getAllFavorites(); return buildFavoriteList(context); } ), ); }Navigator.push(context, MaterialPageRoute( builder: (_) => BlocProvider.value( value: context.read<FavoritesCubit>(), child: const FavoriteView(), ) )); - 重构FavoritesCubit的状态管理逻辑
删除Cubit中单独声明的favoriteList属性,所有列表数据统一放到FavoritesState中维护,遵循Bloc的不可变数据更新规则,不要直接修改原状态内的列表:class FavoritesCubit extends Cubit<FavoritesState> { FavoritesCubit() : super(const FavoritesState(favoriteList: [])); Future<void> getAllFavorites() async { print("FavoriteList : ${state.favoriteList.length}"); emit(state.copyWith()); } // 移除方法里的BuildContext参数,Cubit业务逻辑不需要持有上下文 Future<void> addFavorite(PhotoModel photo) async { photo.isSelected = !photo.isSelected; // 基于当前状态的列表做新拷贝,不直接修改原列表 final updatedList = List<PhotoModel>.from(state.favoriteList); if (!updatedList.contains(photo)) { updatedList.add(photo); } else { updatedList.remove(photo); } emit(state.copyWith( favoriteList: updatedList, isFavorite: photo.isSelected )); print("当前收藏列表长度:${state.favoriteList.length}"); } } - 调整首页的收藏点击逻辑
移除多余的方法参数和重复调用,addFavorite执行时已经会触发状态更新,不需要额外调用getAllFavorites:onTap: () { final currentPhoto = state.selectItem![index]; context.read<FavoritesCubit>().addFavorite(currentPhoto); print(currentPhoto.isSelected); },
内容的提问来源于stack exchange,提问作者fracky96
相关产品推荐
相关产品推荐

