由于flutter在不同条件下多次调用了build方法,为避免多次获取数据,我在initState中初始化了数据。
我想在数据准备好后重新构建窗口小部件。
这是我的代码:
class Test extends StatefulWidget {
@override
_TestState createState() => new _TestState();
}
class _TestState extends State<Test> {
Data data;
bool dataReady = false;
@override
void initState() {
super.initState();
getData(context).then((Data data) async {
setState(() {
dataReady= true;
});
});
}
@override
Widget build(BuildContext context) {
if (dataReady) {
return createMainContent(context);
} else {
return new Container();
}
}
}
但是,它导致以下异常: _TestState.initState()完成之前,调用了InheritFromWidgetOfExactType(_InheritedProvider)或InheritFromElement()。
我可以知道我在这里做错了吗?
当我将以下行添加到getData(context)的实现中
await Future.delayed(new Duration(milliseconds: 300));
,不会发生异常。
谢谢!
答案 0 :(得分:2)
我将代码从initState移到了build方法,并且有效
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
return View(order);
}
答案 1 :(得分:2)
另一种选择是将其放在<div class="border" style="width: 200px; height:200px">
<div class="mx-auto my-auto border" style="width:20px; height:20px"></div>
</div>
和PostFrameCallback
之间的initState
内。
Build
答案 2 :(得分:1)
显然,您无法在getData(context)
期间访问initState
(更具体的说:在完成之前)。
我相信,原因是getData
试图在树中向上查找InheritedWidget
祖先,但是树正在构建中(您的窗口小部件是在父窗口小部件的创建期间创建的build
。
显而易见的解决方案是将getData
的查找延迟到以后的某个时间点。有几种方法可以实现:
Future.delayed
与Duration.zero
配合使用会很好。在第一个build
调用期间进行查找。您可以将isInitialized
字段设置为false
,在您的build
中,类似以下内容:
if (!isInitialized) {
isInitialized = true;
// TODO: do the getData(...) stuff
}
答案 3 :(得分:1)
以后再来的人
最好使用@override void didChangeDependencies ()
类的State
方法。
从docs
在initState之后也立即调用此方法。从此方法调用BuildContext.inheritFromWidgetOfExactType是安全的。
但是请确保检查您是否已经执行了初始化
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (bloc == null) { // or else you end up creating multiple instances in this case.
bloc = BlocProvider<MyBloc>.of(context);
}
}