多个 yield 调用覆盖之前的状态

时间:2021-06-30 11:50:57

标签: flutter bloc flutter-bloc

我在我的应用程序中使用 Flutter Bloc 进行状态管理。

当使用 .copyWith() 模式连续产生多个新状态时, 未包含在最新 .copyWith() 调用中的状态成员设置为 null。

这种行为是有意为之,还是我的 flutter 和/或 Bloc 版本太旧? 我正在使用 Flutter 1.22.6 和 Flutter_bloc 6.1.3

//my_bloc_state.dart
class MyState extends Equatable {
  final String foo;
  final String bar;

  const MyState({this.foo, this.bar});


  MyState copyWith({
    String foo,
    String bar,
  }) {
    if ((foo == null || identical(foo, this.foo)) &&
        (bar == null || identical(bar, this.bar))) {
      return this;
    }

    return MyState(
      foo: foo ?? this.foo,
      bar: bar ?? this.bar
    );
  }

  @override
  List<Object> get props => [foo, bar];
}



//my_bloc.dart

@override
Stream<MyState> mapEventToState(MyEvent event) async* {
  if (event is MySpecialEvent) {
    yield state.copyWith(foo: "hello");

    yield state.copyWith(bar: "World");

    print(state.foo) // null
  }
}

2 个答案:

答案 0 :(得分:1)

我建议在任何情况下都更新您的库,将来其他依赖项会更容易。 我建议的另一件事是使用 Cubit 方法,并且您的代码已经比原来的 BLoC (https://pub.dev/packages/flutter_bloc) 看起来更像它。 使用 BLoC 时,建议为每个可能的状态更改设置一个事件。

但是让我们在这里看看您的问题。 这段代码:

return MyState(
  foo: foo ?? this.foo,
  bar: bar ?? this.bar
);

表示 MyState 仅在 foobar 不为空时才会更新,如果为空,它将返回之前存在的任何内容。 对我来说不太好的是您的 state 对象尚未更新为 yield,但您正在尝试打印它:

print(state.foo) // null

如果您真的想在 yield 之后查看状态对象的外观,请尝试在之前添加如下内容:

state = state.copyWith(foo: "hello");
print(state.foo);
print(state.bar);

state = state.copyWith(bar: "World");
print(state.foo);
print(state.bar);

yield state;

答案 1 :(得分:0)

认为是这里的问题

   @override
Stream<MyState> mapEventToState(MyEvent event) async* {
  if (event is MySpecialEvent) {
    yield state.copyWith(foo: "hello");

    yield state.copyWith(bar: "World");

    print(state.foo) // null
  }
}

在此之后打印 foo 时

yield state.copyWith(bar: "World");

foo 值为 null,因为您没有在此处为其放置任何值。

yield state.copyWith(foo: "hello");

在此状态后,foo 值为“hello”,bar 值为 null。

yield state.copyWith(bar: "World");

在此状态覆盖之前的状态值后,bar 值为“world”,foo 值默认为 null。

如果您需要为最后一个状态同时获得这两个状态,请按如下所示生成最终状态。

替换最后一条屈服线

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

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

两者都可以