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

如何解决在AsyncValueWidget中修改Provider的构建报错

修复“Tried to modify a provider while the widget tree was building.”错误

错误原因

你在AsyncValueWidget的data回调里直接修改selectedPlansNotifier.state,而这个回调属于Widget构建流程的一部分。Flutter禁止在构建widget树期间修改状态,这会触发不必要的重绘,甚至导致无限循环。

修复方案

方案一:延迟到帧构建完成后执行状态更新

使用WidgetsBinding.instance.addPostFrameCallback将状态修改逻辑推迟到当前帧构建完成后,避开构建阶段:

AsyncValueWidget(
  value: ref.watch(planCategoriesProvider),
  data: (data) {
    // 推迟到当前帧构建完成后更新状态
    WidgetsBinding.instance.addPostFrameCallback((_) {
      selectedPlansNotifier.state = data
          .expand((e) => e.plans)
          .toList()
          .where((e) => profile.plans.map((e) => e.id).contains(e.id))
          .toList();
    });
    return widget;
  },
)

方案二:用ref.listen监听数据变化更新状态(推荐)

将状态更新逻辑从UI构建流程中分离,通过ref.listen监听planCategoriesProvider的变化,自动更新selectedPlansNotifier状态,更符合Riverpod的设计理念:

// 在Widget的初始化逻辑中添加监听(比如ConsumerStatefulWidget的initState)
ref.listen(planCategoriesProvider, (previous, next) {
  next.whenData((data) {
    selectedPlansNotifier.state = data
        .expand((e) => e.plans)
        .toList()
        .where((e) => profile.plans.map((e) => e.id).contains(e.id))
        .toList();
  });
});

// AsyncValueWidget仅负责渲染UI,不再处理状态变更
AsyncValueWidget(
  value: ref.watch(planCategoriesProvider),
  data: (data) => widget,
)

内容的提问来源于stack exchange,提问作者Nguyễn Đức Thành

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:29:58