Flutter中Future.delayed引发无限循环:如何避免持续输出false的低效问题
解决Flutter中无限循环的问题
嘿,我一眼就揪出问题根源啦!你遇到的控制台持续输出false、组件无限重建的问题,核心原因是在build方法里调用了setState,直接触发了死循环:
- 组件首次构建,执行
build里的Future.delayed - 500ms后,
then回调里调用setState,强制组件重新执行build - 新的
build又会再次触发Future.delayed,循环往复停不下来
build方法的职责是描述当前状态下的UI,它会在很多场景下被重复调用(比如状态变化、父组件重建、屏幕旋转等),绝对不能在里面放会修改状态的异步操作!
修复方案:把异步操作移到initState
initState是StatefulWidget初始化时仅执行一次的方法,完美适配这种只需要运行一次的异步逻辑。修改后的代码如下:
class _MyAppState extends State<MyApp> { @override void initState() { super.initState(); // 把异步延迟操作移到这里,仅执行一次 Future.delayed(const Duration(milliseconds: 500)).then((_) { setState(() { opened = false; }); }); // 如果getStorage()是耗时操作,也建议移到这里执行 getStorage(); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Container( color: Colors.green, alignment: Alignment.center, child: AnimatedContainer( duration: const Duration(milliseconds: 3000), height: opened ? 0 : 300, width: opened ? 0 : 300, curve: Curves.fastOutSlowIn, alignment: Alignment.center, child: Lottie.asset('assets/101349-swing.json'), ), ), ), ); } }
额外注意点:
- 你原来代码里
value = "null"完全没用,value是then回调的局部参数,修改它不会影响任何内容,可以直接删掉。 - 如果
getStorage()是异步获取数据的方法,同样不要放在build里,要么移到initState,要么用FutureBuilder来处理数据加载状态,避免重复执行。 - 要是担心组件在Future完成前被销毁导致内存泄漏,可以使用
CancelableOperation来包装Future,在dispose方法里取消操作。
内容的提问来源于stack exchange,提问作者Joe Sutter
相关产品推荐
相关产品推荐

