如何正确使用FutureBuilder
和SetState
?例如,当我创建一个有状态小部件时,它开始加载数据(FutureBuilder),然后我应该用新数据更新列表,所以我使用setState,但它开始循环无穷大(因为我再次重建了小部件),有什么解决方案吗?
class FeedListState extends State<FeedList> {
Future<Null> updateList() async {
await widget.feeds.update();
setState(() {
widget.items = widget.feeds.getList();
});
//widget.items = widget.feeds.getList();
}
@override
Widget build(BuildContext context) {
return new FutureBuilder<Null>(
future: updateList(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new Center(
child: new CircularProgressIndicator(),
);
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Scrollbar(
child: new RefreshIndicator(
child: ListView.builder(
physics:
const AlwaysScrollableScrollPhysics(), //Even if zero elements to update scroll
itemCount: widget.items.length,
itemBuilder: (context, index) {
return FeedListItem(widget.items[index]);
},
),
onRefresh: updateList,
),
);
}
},
);
}
}
实际上,它将循环到无穷大,因为每当调用build
时,也会调用updateList
,并返回一个全新的未来。
您必须保持构建
纯净。它应该只是读取和组合变量和属性,但绝不会引起任何副作用!
另一个注意:您的StateFulWidget
子类的所有字段都必须是final(widget.items=...
不好)。更改的状态必须存储在state
对象中。
class FeedListState extends State<FeedList> {
// no idea how you named your data class...
Future<List<ItemData>> _listFuture;
@override
void initState() {
super.initState();
// initial load
_listFuture = updateAndGetList();
}
void refreshList() {
// reload
setState(() {
_listFuture = updateAndGetList();
});
}
Future<List<ItemData>> updateAndGetList() async {
await widget.feeds.update();
// return the list here
return widget.feeds.getList();
}
@override
Widget build(BuildContext context) {
return new FutureBuilder<List<ItemData>>(
future: _listFuture,
builder: (BuildContext context, AsyncSnapshot<List<ItemData>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return new Center(
child: new CircularProgressIndicator(),
);
} else if (snapshot.hasError) {
return new Text('Error: ${snapshot.error}');
} else {
final items = snapshot.data ?? <ItemData>[]; // handle the case that data is null
return new Scrollbar(
child: new RefreshIndicator(
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(), //Even if zero elements to update scroll
itemCount: items.length,
itemBuilder: (context, index) {
return FeedListItem(items[index]);
},
),
onRefresh: refreshList,
),
);
}
},
);
}
}
问题内容: 我是React.js库的新手,我正在浏览一些教程,发现了: 给出的说明不是很清楚(IMO)。 同样, 我先尝试 然后 再进行console.logging它们,发现现在同时具有和。 然后,我 依次尝试 ,然后进行console.logging它们,发现它们又具有和。 那么,两者之间到底有什么区别? 问题答案: 与当前和以前的状态合并。使用,它将抛出当前状态,并仅用您提供的状态替换它。通
我有一个带有ListView的FutureBuilder来显示自定义项(小部件),其值是从。txt文件中读取的。 问题是,只有当我在调试模式或运行模式下启动应用程序时,这些项才会显示。当我试图用AppLauncher打开应用程序时(就像“普通”用户会这样做一样),listView是空的。我在一个AVD和一个“真正的”设备上试过这个。
问题内容: 我在ReactJS项目中一直在使用babel的async await。我发现可以方便地与React setState一起使用,我想更好地理解它。考虑以下代码: 我的意图是让异步验证代码在组件更新后运行。而且有效!生成的控制台日志显示: 验证代码仅在handleChange更新状态并呈现新状态后运行。 通常要在状态更新后运行代码,您必须在this.setState之后使用回调。这意味着,
我想使用的与chrome API,但我遇到了一个问题... 我尝试了以下操作,但chrome API无法将识别为函数,因此我尝试先将保存为变量。。。 但是当我尝试以下操作时,仍然是一个空字符串。我不明白为什么,因为被设置为。我怎样才能解决这个问题? 编辑 我把剧本叫做... 在剧本里我有以下内容... 其中函数只返回一个字符串。它是由我的捕获的,我通过打印到if语句内的控制台来验证它。 我注意到是
问题内容: 我有调度动作的功能。我想在操作之前和之后显示一个加载程序。我知道将对象传递给时会做出反应。问题是如何以异步方式更新属性: 基本上,如果我将此属性作为应用程序状态的一部分(使用Redux),那么一切都很好,但是我真的更喜欢将此属性仅带到组件状态。 问题答案: 将其余代码包装在第一个的回调中: 有了这个,你可以保证被设定为之前被调用,并且被设置回。 这假设您的功能是同步的。如果不是,则将其
问题内容: 在过去的几天里,我一直在学习React,研究一些有关编写不同元素的不同方式的教程和说明。但是,我最想知道的是- 更新/覆盖组件属性的功能。 例如,假设我有一个包含以下内容的类: 这个例子让我从API获取图像。 鉴于我已经执行了此函数的获取,映射和返回操作-然后,我将使用在API调用中获得的结果来更新状态数组。 我的问题源于我所见过的关于如何更新/覆盖图片状态属性的不同方法。 我看到它以