setState对FutureBuilder的使用

如何使用FutureBuildersetState正常吗?例如,当我创建一个有状态的小部件时,它开始加载数据(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也被调用并返回全新的未来。

你必须保持build纯洁。它应该只读取并组合变量和属性,但绝不会引起任何副作用!


另一个注意事项:StatefulWidget子类的所有字段都必须为final(widget.items =

...不好)。更改的状态必须存储在State对象中。

在这种情况下,您可以将结果(列表中的数据)存储在将来的本身中,而无需单独的字段。setState从将来调用它甚至很危险,因为将来可能会在处置状态之后完成,并且会引发错误。

这是一些考虑了所有这些因素的更新代码:

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,

),

);

}

},

);

}

}

以上是 setState对FutureBuilder的使用 的全部内容, 来源链接: utcz.com/qa/399148.html

回到顶部