flutter Bloc,状态改变BlocBuilder不刷新的问题踩坑

起初是用户star和unstar的操作,逻辑代码写的都很顺利,

FloatingActionButton(
                    onPressed: () {
                      BlocProvider.of(context)
                          .add(StarEvent(state.illusts));
                    },
                    child: Icon(Icons.star),
                    foregroundColor:
                        state.illusts.isBookmarked ? Colors.red : Colors.white))

bloc

      if (!event.illusts.isBookmarked) {
        try {
          Response response =
              await client.postLikeIllust(event.illusts.id, "public", null);
  
          yield DataState(event.illusts..isBookmarked=true);
        } catch (e) {}
      } else {
        try {
          Response response = await client.postUnLikeIllust(event.illusts.id);
          yield DataState(event.illusts..isBookmarked=false);
        } catch (e) {}
      }

这一部分是写在BlocBuilder里的,照理来说,当我在Bloc里yield了新的state,那么按钮的color就会刷新
结果我发现,他永远都只会执行第一次的变化
找了半天设定上的问题和issue以及文档,发现BlocBuilder有个condition的属性

/// Signature for the condition function which takes the previous [state] and the current [state]
/// and is responsible for returning a [bool] which determines whether or not to rebuild
/// [BlocBuilder] with the current [state].
typedef BlocBuilderCondition = bool Function(S previous, S current);

我注意到,这里的设计是为了判断是否需要rebuild组件里的内容
猜想,会不会是因为它内部的逻辑代码判断,我的illust指针指的是同一个内存地址,他判断prop是同等的,所以不给rebuild?
于是我重新实例化了一个Illusts对象,然后event.illusts拷贝过来,把新的对象作为实参prop传给state,果然大功告成

          Illusts illusts = Illusts.fromJson(event.illusts.toJson());
          illusts.isBookmarked = true; //降智时间
          yield DataState(illusts);

踩坑成功,顺便吐槽一些似乎dart并没有比较方便的clone对象的功能

更新

也可将DataState继承的BaseState实现的equatable去掉,就不会对props内容进行对比,不过官方doc并不推荐这种做法

你可能感兴趣的:(flutter)