Flutter Hydrated Cubit状态无法持久化:初始状态覆盖已加载状态
问题解决:Hydrated Cubit状态被初始状态覆盖的修复方案
核心问题分析
你的日志显示fromJson已成功加载持久化状态,但随后被初始状态覆盖,根源在于以下几点:
- 状态类未正确实现序列化/反序列化方法,且未重写Equatable的
props属性 - 可能存在Cubit重复实例化或手动触发初始状态的操作
- 未确保HydratedStorage的正确初始化
具体修复步骤
1. 补全状态类的序列化逻辑
你的DefectSectionsState、DefectSection、DefectItem类需要实现fromMap和toMap方法,同时重写Equatable的props以保证状态对比正确性:
class DefectSectionsState extends Equatable { final List<DefectSection> defectSections; const DefectSectionsState({ required this.defectSections, }); factory DefectSectionsState.initial() => const DefectSectionsState( defectSections: [ DefectSection( sectionName: 'FABRIC', defectItems: [DefectItem(name: 'Cotton')], ), DefectSection( sectionName: 'COLOR', defectItems: [DefectItem(name: 'Crimson')], ), DefectSection( sectionName: 'SEWING', defectItems: [DefectItem(name: 'Lockstitch')], ), ], ); // 反序列化方法 factory DefectSectionsState.fromMap(Map<String, dynamic> map) { return DefectSectionsState( defectSections: List<DefectSection>.from( map['defectSections'].map((x) => DefectSection.fromMap(x)), ), ); } // 序列化方法 Map<String, dynamic> toMap() { return { 'defectSections': defectSections.map((x) => x.toMap()).toList(), }; } @override List<Object> get props => [defectSections]; } class DefectSection extends Equatable { final String sectionName; final List<DefectItem> defectItems; const DefectSection({ required this.sectionName, required this.defectItems, }); factory DefectSection.fromMap(Map<String, dynamic> map) { return DefectSection( sectionName: map['sectionName'], defectItems: List<DefectItem>.from( map['defectItems'].map((x) => DefectItem.fromMap(x)), ), ); } Map<String, dynamic> toMap() { return { 'sectionName': sectionName, 'defectItems': defectItems.map((x) => x.toMap()).toList(), }; } @override List<Object> get props => [sectionName, defectItems]; } class DefectItem extends Equatable { final String name; const DefectItem({required this.name}); factory DefectItem.fromMap(Map<String, dynamic> map) { return DefectItem(name: map['name']); } Map<String, dynamic> toMap() { return {'name': name}; } @override List<Object> get props => [name]; }
2. 正确初始化HydratedStorage
在main函数中必须先初始化存储,否则持久化逻辑无法正常工作:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化Hydrated存储目录 HydratedBloc.storage = await HydratedStorage.build( storageDirectory: await getApplicationDocumentsDirectory(), ); runApp(const YourApp()); }
3. 避免Cubit重复实例化或手动覆盖状态
- 确保在Widget树中仅创建一次Cubit实例,比如使用
BlocProvider的懒加载模式:BlocProvider( create: (context) => DefectSectionsCubit(), lazy: true, // 默认开启,仅在需要时创建实例 child: YourPage(), ) - 检查代码中是否存在手动调用
emit(DefectSectionsState.initial())的逻辑,这类操作会直接覆盖已加载的持久化状态。
4. 保持Cubit代码简洁
你的Cubit代码无需修改构造函数,保持原有结构即可:
class DefectSectionsCubit extends HydratedCubit<DefectSectionsState> { DefectSectionsCubit() : super(DefectSectionsState.initial()) { print("Cubit initialized"); } @override DefectSectionsState? fromJson(Map<String, dynamic> json) { print("Loaded state from storage"); return DefectSectionsState.fromMap(json); } @override Map<String, dynamic>? toJson(DefectSectionsState state) { print("Saved state to storage"); return state.toMap(); } // 自定义状态更新方法示例 void updateSections(List<DefectSection> newSections) { emit(DefectSectionsState(defectSections: newSections)); } }
内容的提问来源于stack exchange,提问作者kk-at-cbx
相关产品推荐
相关产品推荐

