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的现象
- 第一次yield的状态
- 最后
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
相关产品推荐
相关产品推荐

