Dart中两种setState()用法的差异是什么?
两种setState()用法的差异及问题分析
第一种写法:异步操作嵌套在setState回调内
// == Add all picked idoes to the mix table setState(() { Future.forEach(result, (asset) async { final video = await MixTableVideo.create(original: asset); videos.add(video); }); });
- 核心问题:
setState的回调设计为同步执行,目的是在同步代码块内完成状态修改,让Flutter框架精准捕获状态变化。但这里的Future.forEach是异步操作,会立即返回,setState回调会提前执行完毕。后续异步逻辑中对videos的修改,完全脱离了setState的同步上下文,Flutter无法感知到这次状态变更,最终UI不会更新。这种写法本身就违背了setState的使用规范。
第二种写法:异步操作后立即调用setState
// == Add all picked idoes to the mix table Future.forEach(result, (asset) async { final video = await MixTableVideo.create(original: asset); videos.add(video); }); setState(() {});
- 核心问题:
Future.forEach是异步任务,调用后不会阻塞后续代码执行。也就是说,setState会在异步任务还未完成时就被调用,此时videos还没有被添加任何新元素。这次setState触发的UI重建,只会显示videos的旧状态。等后续异步任务完成、videos实际更新后,因为没有再次调用setState,UI也不会同步更新到最新数据。
正确的实现方式
要保证UI能正确更新,必须等所有异步操作完成后,再调用setState通知框架:
await Future.forEach(result, (asset) async { final video = await MixTableVideo.create(original: asset); videos.add(video); }); setState(() {});
或者封装成独立的异步函数:
void addPickedVideos() async { await Future.forEach(result, (asset) async { final video = await MixTableVideo.create(original: asset); videos.add(video); }); setState(() {}); } // 调用函数触发流程 addPickedVideos();
通过await等待所有视频添加完成后再执行setState,能确保UI重建时使用的是最新的videos数据,实现预期的更新效果。
内容的提问来源于stack exchange,提问作者Stéphane de Luca
相关产品推荐
相关产品推荐

