使用Equatable后Bloc emit属性不同的同状态仍不触发Builder
问题原因及解决方案
核心问题
Bloc不触发重建的根本原因是新旧状态的reports列表引用相同,Equatable比较时会判定状态未发生变化。Dart中List属于可变对象,你直接将event.curr_reports赋值给updated_reports,后续修改列表元素时,列表本身的引用并未改变,导致Equatable认为新旧ReportsLoadSuccess状态相等,因此Bloc不会通知UI重建。
另外需确保Report和Message类也正确继承并实现Equatable,否则即使列表引用改变,Equatable也无法准确检测到内部元素的变化。
修复步骤
创建列表的全新副本
在_OnReportMessageSubmitted方法中,不要直接复用原列表引用,而是创建新的列表副本,断开与原状态列表的关联:// 替换原有赋值方式,生成新列表 List<Report> updated_reports = [...event.curr_reports]; // 也可使用List.from方式 // List<Report> updated_reports = List.from(event.curr_reports);确保Report类实现Equatable
Report类需要继承Equatable,并将reportId、messages等核心属性加入props,保证元素内容变化时能被Equatable检测到:class Report extends Equatable { final String reportId; final List<Message> messages; // 其他属性... const Report({required this.reportId, required this.messages}); Report copyWith({ String? reportId, List<Message>? messages, }) { return Report( reportId: reportId ?? this.reportId, messages: messages ?? this.messages, ); } @override List<Object> get props => [reportId, messages]; }确保Message类实现Equatable
Message类同样需要正确实现Equatable,保证消息内容的变化能被上层列表的Equatable比较感知:class Message extends Equatable { final String id; final String content; // 其他属性... const Message({required this.id, required this.content}); factory Message.fromJson(Map<String, dynamic> json) { return Message( id: json['id'], content: json['content'], ); } @override List<Object> get props => [id, content]; }
修改后的_bloc方法代码
void _OnReportMessageSubmitted( ReportMessageSubmitted event, Emitter<ReportsState> emit, ) async { final DataState dataState = await _reportsRepository.addMessage(event.messageData); if (dataState is DataSuccess) { // 创建列表副本,断开原引用 List<Report> updated_reports = [...event.curr_reports]; int index = updated_reports.indexWhere( (_element) => _element.reportId == dataState.data['reportConvId'], ); updated_reports[index] = updated_reports[index].copyWith( messages: [ ...updated_reports[index].messages, Message.fromJson(dataState.data), ], ); emit(ReportsLoadSuccess(updated_reports)); } else { //... } }
内容的提问来源于stack exchange,提问作者Abdeljalil Bouchfar
相关产品推荐
相关产品推荐

