如何解决在 Widget 的 initState 中使用 Provider 或初始化生命周期
所以在学习 Flutter 时,似乎 initState()
不是使用 Providers 的地方,因为它还没有访问必须传递的 context
。我的导师解决这个问题的方法是将 didChangeDependencies()
生命周期钩子与一个标志结合使用,这样里面的任何代码都不会多次运行:
bool _isInit = true;
@override
void didChangeDependencies() {
if (_isInit) {
// Some provider code that gets/sets some state
}
_isInit = false;
super.didChangeDependencies();
}
这对我来说是一种糟糕的开发体验。有没有其他方法可以在可以访问 context
的 Flutter Widget 中运行初始化代码?或者有没有计划推出更可行的东西?
我见过的唯一另一种方法是使用 Future.delayed
,这感觉有点“hacky”:
@override
void initState() {
Future.delayed(Duration.zero).then(() {
// Some provider code that gets/sets some state
});
super.initState();
}
解决方法
我在 didChangeDependencies 里面实现如下
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (_isInit) {
setState(() {
_isLoading = true;
});
Provider.of<Products>(context).fetchAndSetProducts().then((_) {
setState(() {
_isLoading = false;
});
});
}
_isInit = false;
}
,
可以安排代码在当前帧的末尾运行。如果在 initState()
内安排,那么在代码运行时,Widget 似乎已完全设置。
为此,您可以使用 SchedulerBinding
实例的 addPostFrameCallback 方法:
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
// Some provider code that gets/sets some state
})
}
您也可以为此使用 WidgetsBinding.instance.addPostFrameCallback()
。为了在构建/加载 Widget 后运行一次代码,它们的行为是相同的,但 here 是关于差异的更多细节。
注意:一定要导入SchedulerBinding需要的文件:
import 'package:flutter/scheduler.dart';
,
您可以在单独的函数中使用 Provider 并在 initState()
bool isInit = true;
Future<void> fetch() async {
await Provider.of<someProvider>(context,listen: false).fetch();
}
@override
void initState() {
if (isInit) {
isInit = false;
fetch();
}
isInit = false;
super.initState();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。