如何解决在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
相关产品推荐
相关产品推荐

