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

flutter_bloc从v7.2.1升级v8.0.0后事件无法触发问题排查

问题根因

这是flutter_bloc v8版本升级后的常见写法错误,核心有2处问题,无编译报错是因为Dart中void类型回调的返回值会被自动忽略,语法上合法但逻辑上不会执行对应方法:

  • 事件回调仅返回了方法引用,没有实际执行方法:v8的on<Event>回调不要求返回Stream,你当前写的(event, emit) => _getMonks只是把方法本身作为返回值抛出,并没有调用_getMonks函数
  • 事件参数传递不匹配:_searchMonks方法需要接收String类型的query参数,你需要从MonkSearchEvent事件实例中取出query属性再传入方法

修复方案

方案1:兼容原有async*方法写法

使用emit.forEach消费原有方法返回的状态Stream即可:

class MonkBloc extends Bloc<MonkEvent, MonkState> {
   final MonkRespository monkRespository;
   late List<Monk> monks;

   MonkBloc({required this.monkRespository}) : super(MonkInitial()) {
       on<GetMonksEvent>((event, emit) async {
         await emit.forEach(_getMonks(emit), onData: (state) => state);
       });
       on<MonkSearchEvent>((event, emit) async {
         await emit.forEach(_searchMonks(event.query, emit), onData: (state) => state);
       });
   }

   Stream<MonkState> _getMonks(Emitter<MonkState> emit) async* {
     emit(MonkLoading());
     try {
        final List<Monk> monks = await monkRespository.fetchMonks();
        emit(MonkLoaded(monks: monks));
     } catch (e) {
       emit(MonkError(error: e.toString()));
     }
  }

  Stream<MonkState> _searchMonks(String query, Emitter<MonkState> emit) async* {
    emit(MonkLoading());
    try {
      final List<Monk> monks = await monkRespository.searchMonks(query);
      emit(MonkLoaded(monks: monks));
    } catch (e) {
      emit(MonkError(error: e.toString()));
    }
  }
}

方案2:更符合v8设计规范的简化写法(推荐)

直接把业务逻辑写到事件回调中,不需要单独维护返回Stream的方法,代码更直观:

class MonkBloc extends Bloc<MonkEvent, MonkState> {
   final MonkRespository monkRespository;
   late List<Monk> monks;

   MonkBloc({required this.monkRespository}) : super(MonkInitial()) {
       on<GetMonksEvent>((event, emit) async {
         emit(MonkLoading());
         try {
            final List<Monk> monks = await monkRespository.fetchMonks();
            emit(MonkLoaded(monks: monks));
         } catch (e) {
           emit(MonkError(error: e.toString()));
         }
       });
       on<MonkSearchEvent>((event, emit) async {
         emit(MonkLoading());
         try {
            final List<Monk> monks = await monkRespository.searchMonks(event.query);
            emit(MonkLoaded(monks: monks));
         } catch (e) {
           emit(MonkError(error: e.toString()));
         }
       });
   }
}

内容的提问来源于stack exchange,提问作者Alex Aung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:09:02