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

Freezed+Bloc:如何在Bloc Listener中判断状态并获取特定状态变量

如何在Bloc监听器中访问Success状态的code变量

我正在学习如何在Bloc监听器中根据状态,以及仅在Success状态中存在的code变量执行代码。需要在Listener中判断当前是否处于Success状态,并获取该状态下的code值。

现有代码实现

状态定义

@freezed
class ExampleState with _$ExampleState {
  const factory ExampleState.initial() = _Initial;
  const factory ExampleState.success(int code) = _Success;
  const factory ExampleState.error() = _Error;
}

Bloc逻辑

class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
  ExampleBloc() : super(_Initial()) {
    on<_ChangeCode>((event, emit) {
      if(state is _Success){
        int stateCode = (state as _Success).code;
        debugPrint("Ey, I got the current code:  $stateCode");
        // 希望在Listener中以类似方式访问该code变量
      }
      emit(ExampleState.success(event.newCode));
    });
  }
}

待完善的Listener代码

listener: (context, state) {
  // 希望判断当前状态是否为success
  // 希望在state.code == 5时打印内容
},

我尝试的两种方案

方案一:为所有状态添加code变量

修改状态定义,给每个状态都添加code参数,这样可以直接通过state.code访问:

@freezed
class ExampleState with _$ExampleState {
  const factory ExampleState.initial(int code) = _Initial;
  const factory ExampleState.success(int code) = _Success;
  const factory ExampleState.error(int code) = _Error;
}

对应的Listener代码:

listener: (context, state) {
  debugPrint(state.code.toString());
},

但这个方案的缺点很明显:很多状态(比如initial、error)根本不需要code字段,长期维护会产生冗余代码,还可能引入无意义的默认值。

方案二:将Success状态类设为公开

把_Success前的下划线去掉,改为公开的Success类:

@freezed
class ExampleState with _$ExampleState {
  const factory ExampleState.initial() = _Initial;
  const factory ExampleState.success(int code) = Success;
  const factory ExampleState.error() = _Error;
}

对应的Listener代码:

listener: (context, state) {
  if(state is Success){
    debugPrint(state.code.toString());
    if (state.code == 5) {
      debugPrint('Code matches 5!');
    }
  }
},

但我不确定这种做法是否属于不良实践,因为默认生成的状态类是私有的,不知道是否应该修改这个规则。

解答:公开特定状态类是合理实践

Freezed默认生成私有状态类(带下划线)是为了强制开发者通过工厂构造函数创建状态,避免直接实例化状态子类。但将需要外部访问的状态类设为公开是完全合规且推荐的做法,原因如下:

  • 当UI层或其他外部代码需要区分状态类型并访问特定状态的属性时,公开对应的状态类是最直接、类型安全的方式。
  • 避免了方案一中冗余字段的问题,保持状态结构的清晰性。

另外,推荐使用Freezed提供的when方法进行模式匹配,代码会更简洁且符合Freezed的设计理念:

listener: (context, state) {
  state.when(
    initial: () {}, // 处理初始状态
    success: (code) {
      if (code == 5) {
        debugPrint('Code is 5!');
      }
    },
    error: () {}, // 处理错误状态
  );
}

这种方式不需要手动进行类型判断和转换,编译器会自动检查所有状态分支,避免遗漏情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:43:21