Flutter:仅特定字段变更时阻止Hydrated Bloc保存状态到JSON
解决Hydrated Bloc忽略特定字段变更的优雅方案
方案一:重写shouldPersist方法(推荐)
Hydrated Bloc原生提供了shouldPersist方法,专门用来判断是否需要持久化当前状态。你可以在自定义的HydratedBloc中重写这个方法,通过对比新旧状态的字段,仅当非Matrix4的核心字段发生变化时才允许持久化。
示例代码:
class MapBloc extends HydratedBloc<MapEvent, MapState> { MapBloc() : super(MapState.initial()) { // 事件处理逻辑 } @override bool shouldPersist(MapState previousState, MapState currentState) { // 仅当实体列表或其他核心字段变化时,返回true触发持久化 return previousState.entityList != currentState.entityList || previousState.filterCondition != currentState.filterCondition || previousState.selectedId != currentState.selectedId; // 若只有Matrix4变化,上述条件不满足,返回false跳过持久化 } @override MapState? fromJson(Map<String, dynamic> json) { // 从JSON恢复核心状态的逻辑 return MapState( entityList: List<Entity>.from(json['entities'].map((e) => Entity.fromJson(e))), filterCondition: json['filter'], selectedId: json['selectedId'], transformationMatrix: Matrix4.identity(), // 临时状态从初始值恢复 ); } @override Map<String, dynamic>? toJson(MapState state) { // 仅序列化核心字段,无需处理Matrix4 return { 'entities': state.entityList.map((e) => e.toJson()).toList(), 'filter': state.filterCondition, 'selectedId': state.selectedId, }; } }
这个方案贴合Hydrated Bloc的设计逻辑,无需额外维护状态副本,代码更简洁易维护。
方案二:拆分状态结构
把状态拆分为持久化核心状态和临时交互状态两部分,仅将核心状态交给Hydrated Bloc管理,Matrix4这类临时状态单独存储在Bloc的成员变量或单独的Cubit中。
示例代码:
// 仅包含需要持久化的核心字段 class PersistentMapState { final List<Entity> entityList; final String filterCondition; final String? selectedId; PersistentMapState({ required this.entityList, required this.filterCondition, this.selectedId, }); // 实现copyWith、fromJson、toJson方法 } // 完整UI状态,包含临时交互字段 class MapState { final PersistentMapState persistentState; final Matrix4 transformationMatrix; MapState({ required this.persistentState, required this.transformationMatrix, }); MapState copyWith({ PersistentMapState? persistentState, Matrix4? transformationMatrix, }) { return MapState( persistentState: persistentState ?? this.persistentState, transformationMatrix: transformationMatrix ?? this.transformationMatrix, ); } } class MapBloc extends HydratedBloc<MapEvent, MapState> { MapBloc() : super(MapState( persistentState: PersistentMapState(entityList: [], filterCondition: ''), transformationMatrix: Matrix4.identity(), )) { // 更新临时矩阵时,仅更新transformationMatrix,不触发持久化 on<UpdateMatrixEvent>((event, emit) { emit(state.copyWith(transformationMatrix: event.newMatrix)); }); // 更新核心字段时,更新persistentState,自动触发持久化 on<UpdateEntityListEvent>((event, emit) { final newPersistentState = state.persistentState.copyWith(entityList: event.newList); emit(state.copyWith(persistentState: newPersistentState)); }); } @override MapState? fromJson(Map<String, dynamic> json) { final persistentState = PersistentMapState.fromJson(json); return MapState( persistentState: persistentState, transformationMatrix: Matrix4.identity(), // 临时状态无需持久化 ); } @override Map<String, dynamic>? toJson(MapState state) { return state.persistentState.toJson(); } }
这种方案彻底分离了持久化和临时状态,避免了字段对比逻辑,状态结构更清晰,适合状态字段较多的复杂场景。
内容的提问来源于stack exchange,提问作者capow20
相关产品推荐
相关产品推荐

