我在我的应用程序中使用 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
}
}
答案 0 :(得分:1)
我建议在任何情况下都更新您的库,将来其他依赖项会更容易。
我建议的另一件事是使用 Cubit
方法,并且您的代码已经比原来的 BLoC
(https://pub.dev/packages/flutter_bloc) 看起来更像它。
使用 BLoC
时,建议为每个可能的状态更改设置一个事件。
但是让我们在这里看看您的问题。 这段代码:
return MyState(
foo: foo ?? this.foo,
bar: bar ?? this.bar
);
表示 MyState
仅在 foo
和 bar
不为空时才会更新,如果为空,它将返回之前存在的任何内容。
对我来说不太好的是您的 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);
两者都可以