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

Flutter中使用FutureBuilder触发build阶段更新异常的问题咨询

问题分析与解决方案

错误根源

你的问题核心出在DoctorsProvider.getDoctors()的同步触发逻辑上:

  • 虽然方法标记了async,但内部给_doctors赋值Mock数据后,立刻同步调用了notifyListeners()。当你在initState或组件build阶段执行这个Future时,组件正处于构建流程中,此时触发状态通知会导致框架抛出「setState() or markNeedsBuild() called during build.」异常。
  • 另外,你最初的Stateless组件写法有隐性问题:直接把_refreshDoctors(context)传给FutureBuilder的future参数,会导致每次组件构建都重新创建Future,触发FutureBuilder反复重建——不过转成Stateful后这个问题已经解决,但同步通知的bug依然存在。

修复方案

方案1:延迟状态通知到构建完成后

修改DoctorsProvider的getDoctors方法,用Future.microtask把状态通知延迟到当前构建周期结束后执行:

Future<void> getDoctors() async {
  _doctors = MockedDoctorsProvider().doctors;
  // 延迟触发通知,避开组件构建阶段
  await Future.microtask(() => notifyListeners());
}

方案2:模拟真实异步请求逻辑

如果是模拟接口请求,给Mock数据的获取添加异步延迟,让Future真正进入异步队列执行:

Future<void> getDoctors() async {
  // 哪怕是0时长延迟,也能让Future脱离同步构建流程
  await Future.delayed(const Duration(milliseconds: 0));
  _doctors = MockedDoctorsProvider().doctors;
  notifyListeners();
}

额外说明

你当前的Stateful组件写法是正确的(把Future存在成员变量里,避免每次构建重建Future),保持即可。另外不存在无限循环:Consumer只会在notifyListeners()触发时重建对应部分,只要不在Consumer的builder回调里调用getDoctors(),就不会出现循环重建的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:19:53