You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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核心代码:
    @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);
          }
        ),
      );
    }
    
    如果是直接push路由跳转,传参示例:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:54:31