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

Flutter Bloc连续多次yield状态时旧属性被置空是否为预期行为?

原因说明

该行为是Bloc的预期设计,和你使用的Flutter、flutter_bloc版本无关。
核心逻辑如下:

  • mapEventToState方法中访问的state是当前事件触发时Bloc持有的状态快照,整个当前事件的处理周期内,这个引用不会自动同步Bloc内部的最新状态,哪怕你中间已经yield了新状态。
  • 你代码中的两次copyWith调用都是基于事件触发时的初始状态(foo、bar均为null)执行的:
    • 第一次yield的状态foo为hello,bar为null,此时Bloc内部的state已经更新,但你代码里持有的state变量还是初始值
    • 第二次调用state.copyWith(bar: "World")依然基于初始状态生成新对象,所以新状态的bar为World,foo为null,也就出现了你看到的未传参数被置为null的现象
  • 最后print(state.foo)输出null也是同理,state始终是事件触发时的初始快照。
解决方案

如果你需要基于前一步修改后的状态继续迭代,需要手动持有上一步生成的新状态实例:

@override
Stream<MyState> mapEventToState(MyEvent event) async* {
  if (event is MySpecialEvent) {
    // 手动存储第一步修改后的状态
    final updatedState1 = state.copyWith(foo: "hello");
    yield updatedState1;

    // 基于第一步的新状态继续修改
    final updatedState2 = updatedState1.copyWith(bar: "World");
    yield updatedState2;

    print(updatedState2.foo) // 输出 hello
  }
}

如果你不需要对外暴露中间状态,可以直接一次copyWith修改所有需要更新的字段:

yield state.copyWith(foo: "hello", bar: "World");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 17:15:04