Flutter Cubit搜索状态回退异常问题排查求助
笔记搜索功能Cubit状态更新异常修复
问题现象
- 输入“o”时,能正确过滤出包含“o”的笔记;
- 输入“on”时,过滤结果正常;
- 但回退到“o”时,Cubit的state变为“on”对应的过滤结果,无法基于原始全量数据重新过滤,导致丢失部分结果。
示例:
- 原始全量笔记:
["one","only","two","five"] - 输入“o”:过滤结果为
["one","only","two"],此时Cubit state被替换为该结果; - 输入“on”:基于已过滤的state再过滤,得到
["one","only"]; - 回退到“o”:只能基于
["one","only"]过滤,结果与该列表一致,丢失了原有的"two"。
问题根源
NoteCubit的searchNote方法每次emit过滤后的列表,直接覆盖了存储原始全量数据的state,导致后续搜索无法基于完整数据集重新过滤。
解决方案
在NoteCubit内部维护一个独立的全量笔记数据源,所有数据修改操作同步更新该数据源,搜索操作始终基于全量数据源进行过滤,仅emit过滤后的结果,不修改全量数据源。
修改后的NoteCubit代码
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:notecraft/data/models/note_model.dart'; class NoteCubit extends Cubit<List<Note>> { // 维护全量笔记数据源 final List<Note> _allNotes = []; NoteCubit() : super([]); void addNote(Note note) { _allNotes.add(note); emit(List.from(_allNotes)); } void emitAllNotes() { emit(List.from(_allNotes)); } List<Note>? getAllNotes() { return List.from(_allNotes); } Note? getNote(int id) { return _allNotes.firstWhere((note) => note.id == id, orElse: () => Note()); } void getOneNote(int id) { emit(_allNotes .where((parseNote) => parseNote.id == id) .map((parseNote) => parseNote) .toList()); } void updateNote(Note note) { final index = _allNotes.indexWhere((n) => n.id == note.id); if (index != -1) { _allNotes[index] = note.copyWith( title: note.title, description: note.description, updated_at: '22-jan-2024', ); emit(List.from(_allNotes)); } } void restoreNote(Note note) { final index = _allNotes.indexWhere((n) => n.id == note.id); if (index != -1) { _allNotes[index] = note.copyWith(isDeleted: 0); emit(List.from(_allNotes)); } } void deleteNote(int id) { _allNotes.removeWhere((note) => note.id == id); emit(List.from(_allNotes)); } void searchNote(String query) { if (query.isEmpty) { emit(List.from(_allNotes)); return; } List<Note> filteredNotes = _allNotes .where((note) => note.title.toLowerCase().contains(query.toLowerCase()) || note.description.toLowerCase().contains(query.toLowerCase())) .toList(); emit(filteredNotes); } }
说明
- 新增
_allNotes私有变量存储全量笔记,所有增删改操作都直接修改该变量,然后emit全量数据的副本; searchNote方法始终基于_allNotes进行过滤,emit过滤后的结果,不会修改全量数据源;- 其他组件(SearchInput、NotesScreen)无需修改,它们监听的Cubit state会根据操作自动更新为全量或过滤后的结果。
内容的提问来源于stack exchange,提问作者user17797226
相关产品推荐
相关产品推荐

