Flutter - Bloc 仅在状态未扩展 Equatable 时发出状态

Posted

技术标签:

【中文标题】Flutter - Bloc 仅在状态未扩展 Equatable 时发出状态【英文标题】:Flutter - Bloc only emits state when the state is not extending Equatable 【发布时间】:2021-01-07 21:00:59 【问题描述】:

我最近开始使用 bloc 并卡在这里。

我有一个状态:

class BasketState extends Equatable
  final Map<Item, int> itemsOrdered;

  BasketState(this.itemsOrdered);

  @override
  List<Object> get props => [itemsOrdered]

还有以下集团:

class BasketBloc extends Bloc<BasketEvent, BasketState> 
  Map<Item, int> _itemsOrdered = ;
  BasketBloc() : super(BasketState());

  @override
  Stream<BasketState> mapEventToState(BasketEvent event) async* 
    if (event is BasketAdd) 
      _itemsOrdered.putIfAbsent(event.item, () => event.amount);
     else if (event is BasketRemove) 
      _itemsOrdered.remove(event.item);
    
    yield BasketState(_itemsOrdered);
  

只有在我第一次发送 BasketAdd 事件时,块才会发出状态,然后如果我再次发送 BasketAdd 事件,块不会发出任何东西。

唯一有效的方法是从状态中删除 Equatable,我不知道为什么。

我做错了吗?

【问题讨论】:

【参考方案1】:

Equatable 正在使用 get props 函数进行比较。

改变

  @override
  List<Object> get props => throw UnimplementedError();

  @override
  List<Object> get props => [itemsOrdered];

再试一次

编辑:答案现在在 cmets 中,但另一个可能的问题是可变性。在这种情况下,我们应该每次都产生一个新的 Map,而不是产生 itemsOrdered。

  yield BasketState(new Map<Item, int>.from(itemsOrdered));

【讨论】:

哦,抱歉,我在写问题的时候忘记了。在我的真实应用中是正确的,现在我编辑了问题。 不幸的是,在那之后我在猜测。一个快速而肮脏的解决方法是产生一个“加载”状态(随便叫什么,BasketLoading)然后再次产生 BasketState。我怀疑正在发生的事情是它正在比较它认为不可变的两个可变对象(地图)。而不是 yield BasketState(_itemsOrdered) 我想知道 yield BasketState(new Map.from(_itemsOrdered)) 是否可行。

以上是关于Flutter - Bloc 仅在状态未扩展 Equatable 时发出状态的主要内容,如果未能解决你的问题,请参考以下文章

使用 copywith 时 Flutter Bloc 状态未更新

Flutter Application Bloc 侦听器未接收到状态更新

BLoC 产生新状态后 BlocBuilder() 未更新

Flutter Bloc 状态更改未使用 get_it 更新 UI

带有和不带有 Equatable 的 Flutter bloc 导航

flutter_bloc 的 BlocBuilder 能否避免重建 Widget 的未更改部分?