我应该在何时何地将值存储在 BLoC 本身或其状态中

Rau*_*abe 7 architecture state-management dart flutter bloc

语境

我来自 Redux,正在学习全局状态管理的 BLoC 模式。我在定义应该将值作为属性存储在 BLoC 类中的位置以及何时应该将值存储在 States 中时遇到困难。

使用案例

我有一个主页,在其中显示一些广告,具体取决于其类别(category不应为空)。我实现了一个这样的 AdsBloc:

class AdsBloc extends Bloc<AdsEvent, AdsState> {
  final AdsRepository repository;
  AdsBloc({@required this.repository})
      : super(AdsInitial(category: Category.DOGS));

  @override
  Stream<AdsState> mapEventToState(
    AdsEvent event,
  ) async* {
    // my code
  }
}
Run Code Online (Sandbox Code Playgroud)

这些是我的 AdsState:

abstract class AdsState {
  final Category category;
  AdsState({this.category});
}

class AdsInitial extends AdsState {
  AdsInitial({category}) : super(category: category);
}

class AdsSuccess extends AdsState {
  final PaginatedAds paginatedAds;
  AdsSuccess({this.paginatedAds, category}) : super(category: category);
}

class AdsFailure extends AdsState {
  AdsFailure({category}) : super(category: category);
}
Run Code Online (Sandbox Code Playgroud)

问题

由于我实现该模式的方式,category每次更改状态时都需要通过。

解决方案?

所以我在想是否可以将类别属性视为AdsBloc并将其从状态中删除,这样我可以更好地控制该属性。

The*_*nut 1

将“类别”实现为触发广告加载过程的事件的参数。例如,您将通过这种方式告诉 BLoC 使用“category: Category.DOGS”来“LoadAds”。

class LoadAds extends AdsEvent {
  final Category category;
  
  LoadAds({
    @required this.category,
  });

  @override
  List<Object> get props => [category];
}
Run Code Online (Sandbox Code Playgroud)

这样,您将能够在需要时使用单个块实例加载不同的广告类型。首先加载 DOGS,2 分钟后加载 CATS 而不是狗。
如果您不需要这种能力 - 那么在 bloc 本身内部定义类别就完全没问题了。