我正在调用初始方法以使用initState从API加载数据。但这导致我出错。这是错误:
Unhandled Exception: inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before _ScreenState.initState() completed.
When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.
我的代码是:
@override
void initState() {
super.initState();
this._getCategories();
}
void _getCategories() async {
AppRoutes.showLoader(context);
Map<String, dynamic> data = await apiPostCall(
apiName: API.addUser,
context: context,
parameterData: null,
showAlert: false,
);
if(data.isNotEmpty){
AppRoutes.dismissLoader(context);
print(data);
}else {
AppRoutes.dismissLoader(context);
}
}
答案 0 :(得分:12)
使用didChangeDependencies方法,该方法在initState之后被调用。
以您的示例为例:
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
this._getCategories();
}
void _getCategories() async {
// Omitted for brevity
// ...
}
答案 1 :(得分:5)
Adding a frame callback可能比使用Future.delayed
且持续时间为零更好-它对正在发生的事情更加明确和清晰,而这种情况就是为帧回调设计的:
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
_getCategories();
});
}
答案 2 :(得分:4)
另一种选择是将其放在PostFrameCallback
和initState
之间的Build
内,这样我们可以确定initState
已经完成。
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
super.initState();
}
getData() async {
}
答案 3 :(得分:1)
尝试在initState之后调用_getCategories
...
Future.dalayed(Duration(miliseconds: 10), () {
this._getCategories();
});
答案 4 :(得分:0)
我认为最好的解决方案是使用Widget构建中的上下文。并在构建后将方法_getCategories(context)与树中的上下文一起粘贴。 因此,小部件树没有问题。
答案 5 :(得分:0)
使用after_init软件包来解决此问题
向有状态的窗口小部件添加didInitState()
生命周期方法,您可以在其中安全地访问继承的窗口小部件。
InheritedWidget
在整个Flutter框架中被大量使用。 ScopedModel和Provider等许多状态管理程序包也都使用它。不幸的是,无法通过InheritedWidgets
的{{1}}方法访问initState()
。
示例:
State
答案 6 :(得分:0)
解决这个问题的方法很多,重写initState
方法:
@override
void initState() {
super.initState();
// Use any of the below code here.
}
使用 SchedulerBinding
混合:
SchedulerBinding.instance.addPostFrameCallback((_) {
// Call your function
});
使用 Future
类:
Future(() {
// Call your function
});
使用 Timer
类:
Timer(() {
// Call your function
});