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

Flutter Bloc使用copyWith()与Equatable后状态仍未更新问题

问题:单选按钮选择后Bloc状态未同步,UI无法实时刷新

核心问题分析

  1. Equatable状态对比失效:SlotsTabbarSuccessState的props数组未包含dummyData,导致Equatable无法检测该字段变化,BlocBuilder不会触发UI重建。
  2. 可变状态修改:直接修改事件传递的dummyData列表元素属性,未创建新列表,违反Bloc状态不可变原则,状态对比时被判定为无变化。
  3. 全局状态实例复用风险:Bloc中维护全局slotsTabbarSuccess实例,复用更新可能导致状态对比异常。

具体修复步骤

1. 修复状态类的props数组

在SlotsTabbarSuccessState的props中添加dummyData,确保Equatable能检测该字段变化:

@override
List<Object> get props => [
      slotData,
      reasonForCancellationEnum,
      isBookedResponseTrue,
      isCancelledResponseTrue,
      markSlotAvailable,
      enableButton,
      isAvailableSlotRadioEnabled,
      isRadioButtonSelected,
      cancellationReason,
      dummyData!, // 新增:将dummyData纳入状态对比
    ];

2. 遵循不可变原则,创建新列表

处理事件时,不直接修改原列表,而是生成新的DummyData对象和列表:

Future<void> _selectAvailablePanelRadioButtonEvent(
    SelectAvailablePanelRadioButtonEvent event,
    Emitter<SlotsTabbarState> emit,
  ) async {
    // 生成新列表,避免修改原状态数据
    final updatedDummyData = event.dummyData.map((data) => DummyData(
          name: data.name,
          designation: data.designation,
          isSelected: data == event.dummyData[event.index],
        )).toList();

    // 从当前状态复制字段,生成新状态实例
    if (state is SlotsTabbarSuccessState) {
      final currentState = state as SlotsTabbarSuccessState;
      emit(currentState.copyWith(
        dummyData: updatedDummyData,
        isAvailableSlotRadioEnabled: true,
        availableSlotEntity: event.availableSlotEntity,
        slotData: event.slotData,
      ));
    }
  }

3. 移除Bloc中的全局状态实例(推荐)

取消全局slotsTabbarSuccess变量,直接从当前状态获取原有字段:

class SlotsTabbarBloc extends Bloc<SlotsTabbarEvent, SlotsTabbarState> {
  final SlotsUsecase slotsUsecase;

  SlotsTabbarBloc(
    this.slotsUsecase,
  ) : super(SlotsTabbarInitial()) {
    on<SelectAvailablePanelRadioButtonEvent>(
      _selectAvailablePanelRadioButtonEvent,
    );
  }

  // 事件处理函数同上...
}

4. 优化事件类参数(可选)

移除事件中无实际作用的isAvailableSlotRadioEnabled参数:

class SelectAvailablePanelRadioButtonEvent extends SlotsTabbarEvent {
  final int index;
  final AvailableSlotEntity availableSlotEntity;
  final List<DummyData> dummyData;
  final List<InterviewSlotDtoListEntity> slotData;

  SelectAvailablePanelRadioButtonEvent({
    required this.index,
    required this.availableSlotEntity,
    required this.dummyData,
    required this.slotData,
  });
}

5. 确认UI正确绑定状态数据

确保UI中单选按钮的选中状态直接从dummyData读取:

// AvailableOnClickPopUpListTile中
isRadioButtonEnabled: state.dummyData![index].isSelected

内容的提问来源于stack exchange,提问作者Srasti Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:10:42