Flutter中FutureBuilder与NotifyListener冲突:加notifyListeners后列表卡加载态
问题原因
- 你在FutureBuilder的
future参数中直接调用Provider.of<EatenMeals>(context).getServerMeals(...),而Provider.of方法的listen参数默认值为true,意味着当前Widget会监听EatenMeals的状态变化。当你在getServerMeals中调用notifyListeners()时,会触发当前页面Widget重建,重建过程中会再次执行getServerMeals方法生成新的Future,FutureBuilder检测到新的Future会重新进入waiting状态,由此形成「请求完成→notify→重建→重新请求」的无限循环,所以一直卡在加载状态。 - 你没有对Future做缓存,每次Widget重建都会重新触发异步请求,无法复用之前的请求结果。
解决方案
- 方案1:调用Provider.of时关闭监听,修改Future参数即可解决:
future: Provider.of<EatenMeals>(context, listen: false) .getServerMeals(currentUser.username, now),
加listen: false后,notifyListeners不会触发该位置的Widget重建,不会重复生成Future,请求完成后FutureBuilder会正常进入完成状态。
- 方案2:在State的
initState生命周期中提前初始化Future,存储为State的变量,再传给FutureBuilder,避免每次重建都重新调用方法:
late Future _loadMealsFuture; @override void initState() { super.initState(); _loadMealsFuture = Provider.of<EatenMeals>(context, listen: false) .getServerMeals(currentUser.username, now); } // FutureBuilder中传入缓存的future future: _loadMealsFuture,
- 方案3:直接适配Provider的状态管理模式,去掉FutureBuilder,在EatenMeals中添加
isLoading状态变量控制加载态,页面直接监听EatenMeals的状态渲染UI即可,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Behnam
相关产品推荐
相关产品推荐

