You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Bloc状态变更后UI不更新,需热重载才生效的问题

Flutter Bloc GridView不刷新问题解决方案

问题根源

你的Bloc中维护了一个可变的noteModel列表,每次添加新笔记后,直接将这个列表的原引用传递给Notes状态并emit。由于Equatable对比props中的列表时是对比引用而非内容,即使列表内容改变,只要引用不变,Bloc会判定前后状态相等,不会触发BlocBuilder重建UI。

另外,若NoteModel未继承Equatable,也会影响Equatable对列表内容的判断(虽非本次问题核心,但建议补充)。

修复方案

1. 每次emit时创建新列表副本

修改Bloc中的SavedNote事件处理逻辑,每次emit新状态时传递列表的新副本,而非原引用:

class NoteBloc extends Bloc<NoteEvent, NoteState> {
  NoteBloc() : super(const Notes([])) {
    final List<NoteModel> noteModel = [];
    on<SavedNote>((event, emit) async {
      noteModel.add(NoteModel(noteModel.length + 1, event.time, event.message));
      await Future.delayed(const Duration(seconds: 1));
      // 创建新列表副本,确保引用不同
      emit(Notes(List.from(noteModel)));
      // 也可使用扩展运算符:emit(Notes([...noteModel]));
    });
  }
}

2. 符合Bloc规范的写法:状态内维护列表(推荐)

Bloc设计原则为状态不可变,应将列表维护在状态中,而非Bloc类的成员变量。每次更新基于旧状态创建新状态:

class NoteBloc extends Bloc<NoteEvent, NoteState> {
  NoteBloc() : super(const Notes([])) {
    on<SavedNote>((event, emit) async {
      await Future.delayed(const Duration(seconds: 1));
      if (state is Notes) {
        final currentNotes = (state as Notes).noteList;
        final newNotes = List.from(currentNotes)
          ..add(NoteModel(currentNotes.length + 1, event.time, event.message));
        emit(Notes(newNotes));
      }
    });
  }
}

3. 确保NoteModel继承Equatable

让Equatable能正确对比列表元素,NoteModel需继承Equatable:

class NoteModel extends Equatable {
  final int id;
  final DateTime time;
  final String message;

  const NoteModel(this.id, this.time, this.message);

  @override
  List<Object?> get props => [id, time, message];
}

额外检查

确认BlocBuilder监听的是正确的Bloc实例,你的代码中弹窗使用当前上下文的Bloc,这部分逻辑是正确的。

修改后,每次添加新笔记时会emit带有新列表引用的Notes状态,Equatable能检测到状态变化,BlocBuilder会立即重建GridView,显示新的笔记卡片。

内容的提问来源于stack exchange,提问作者Tahiru Agbanwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:35:04