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

Cubit中更新Model类值后如何同步更新Widget?

解决Cubit模式下点击GridView项后UI不刷新的问题

直接修改modelCategory对象的字段不会触发UI刷新,因为Cubit只有在发出新的状态时,BlocConsumer才会重新执行builder方法重建UI。你当前的操作只是修改了内存中的数据,但没有通知Cubit更新状态,所以UI不会同步变化。

以下是具体解决方案:

1. 给数据模型添加copyWith方法

Bloc/Cubit的状态应该是不可变的,需要通过复制对象来修改数据,避免直接修改原状态:

// 分类项模型
class Category {
  final String? categoryId;
  final String? categoryName;

  Category({this.categoryId, this.categoryName});

  // 生成新对象的copyWith方法
  Category copyWith({
    String? categoryId,
    String? categoryName,
  }) {
    return Category(
      categoryId: categoryId ?? this.categoryId,
      categoryName: categoryName ?? this.categoryName,
    );
  }
}

// 分类列表模型
class ModelCategory {
  final List<Category>? allCategories;

  ModelCategory({this.allCategories});

  // 生成新对象的copyWith方法
  ModelCategory copyWith({
    List<Category>? allCategories,
  }) {
    return ModelCategory(
      allCategories: allCategories ?? this.allCategories,
    );
  }
}

2. 在Cubit中添加更新分类名称的方法

在CubitCategory类中新增方法,负责复制现有数据、修改指定项,然后发出新的成功状态:

class CubitCategory extends Cubit<StateResponse> {
  CubitCategory() : super(StateResponseInitial());

  // 原有的获取分类方法
  void funcCubitGetCategories() async {
    // ...你的API请求逻辑
  }

  // 新增的更新分类名称方法
  void updateCategoryName(int index, String newName) {
    // 检查当前状态是否为成功状态
    if (state is StateResponseSuccess) {
      final currentData = (state as StateResponseSuccess).data as ModelCategory;
      // 复制分类列表并修改指定项
      final updatedCategories = List.from(currentData.allCategories!)
        ..[index] = currentData.allCategories![index].copyWith(
          categoryName: newName,
        );
      // 生成新的模型对象
      final updatedData = currentData.copyWith(allCategories: updatedCategories);
      // 发出新的成功状态,通知UI更新
      emit(StateResponseSuccess(data: updatedData));
    }
  }
}

3. 修改UI中的点击事件逻辑

把直接修改模型字段的代码,替换为调用Cubit的更新方法:

InkWell(
  onTap: (){
    // 调用Cubit的更新方法,而非直接修改model
    cubitCategory.updateCategoryName(index, "XYz");
  },
  child: Container(
    decoration: BoxDecoration(
      color: Colors.black.withOpacity(.20)
    ),
    child: Column(
      children: [
        Text("${modelCategory.allCategories![index].categoryId}"),
        Text("${modelCategory.allCategories![index].categoryName}"),
      ],
    ),
  ),
),

4. 修复API重复请求问题

你当前在BlocConsumer的bloc参数中调用funcCubitGetCategories(),会导致每次状态变化都重新请求API,需将API请求移到页面的initState中:

class YourPage extends StatefulWidget {
  const YourPage({super.key});

  @override
  State<YourPage> createState() => _YourPageState();
}

class _YourPageState extends State<YourPage> {
  final CubitCategory cubitCategory = CubitCategory();

  @override
  void initState() {
    super.initState();
    // 仅在页面初始化时请求一次分类数据
    cubitCategory.funcCubitGetCategories();
  }

  @override
  void dispose() {
    cubitCategory.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<CubitCategory, StateResponse>(
      bloc: cubitCategory, // 此处不再调用funcCubitGetCategories()
      listener: (context, state) {},
      builder: (context, state) {
        // ...你的原有builder逻辑
      },
    );
  }
}

内容的提问来源于stack exchange,提问作者Dharini Prajapati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:17:02