我什么时候应该使用 FutureBuilder? [英] When should I use a FutureBuilder?
问题描述
我想知道什么时候应该使用未来的构建器.例如,如果我想发出一个 http 请求并在列表视图中显示结果,一旦您打开视图,我应该使用未来的构建器还是只构建一个 ListViewBuilder
像:
I was wondering when I should use the future builder. For example, if I want to make an http request and show the results in a list view, as soon as you open the view, should I have to use the future builder or just build a ListViewBuilder
like:
new ListView.builder(
itemCount: _features.length,
itemBuilder: (BuildContext context, int position) {
...stuff here...
}
此外,如果我不想构建列表视图而是一些更复杂的东西,比如圆形图表,我是否应该使用未来的构建器?
Moreover, if I don't want to build a list view but some more complex stuff like circular charts, should I have to use the future builder?
希望它足够清楚!
推荐答案
FutureBuilder
删除样板代码.
假设您想在页面启动时从后端获取一些数据,并在数据到来之前显示加载器.
Let's say you want to fetch some data from the backend on page launch and show a loader until data comes.
ListBuilder 的任务:
- 有两个状态变量,
dataFromBackend
和isLoadingFlag
- 启动时,设置
isLoadingFlag = true
,并在此基础上显示loader
. - 一旦数据到达,用你从后端得到的设置数据并设置
isLoadingFlag = false
(显然在setState
内部) - 我们需要在小部件创建中使用
if-else
.如果isLoadingFlag
为true
,则显示loader
,否则显示data
.失败时,显示错误消息.
- Have two state variables,
dataFromBackend
andisLoadingFlag
- On launch, set
isLoadingFlag = true
, and based on this, showloader
. - Once data arrives, set data with what you get from backend and set
isLoadingFlag = false
(insidesetState
obviously) - We need to have a
if-else
in widget creation. IfisLoadingFlag
istrue
, show theloader
else show thedata
. On failure, show error message.
FutureBuilder 的任务:
- 在 Future Builder 的
future
中给出异步任务 - 基于
connectionState
,显示消息(loading
,active(streams)
,done
) - 基于
data(snapshot.hasError)
,显示视图
- Give the async task in
future
of Future Builder - Based on
connectionState
, show message (loading
,active(streams)
,done
) - Based on
data(snapshot.hasError)
, show view
FutureBuilder 的优点
- 不使用两个状态变量和
setState
- 响应式编程(
FutureBuilder
将负责在数据到达时更新视图)
- Does not use the two state variables and
setState
- Reactive programming (
FutureBuilder
will take care of updating the view on data arrival)
示例:
FutureBuilder<String>(
future: _fetchNetworkCall, // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return Text('Loading....');
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return Text('Result: ${snapshot.data}');
}
},
)
绩效影响:
我刚刚查看了 FutureBuilder
代码以了解使用它对性能的影响.
I just looked into the FutureBuilder
code to understand the performance impact of using this.
- FutureBuilder 只是一个
StatefulWidget
,它的state
变量是_snapshot
- 初始状态为
_snapshot = AsyncSnapshot
.withData(ConnectionState.none, widget.initialData); - 它订阅了我们通过构造函数发送的
future
,并根据它更新state
.
- FutureBuilder is just a
StatefulWidget
whosestate
variable is_snapshot
- Initial state is
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);
- It is subscribing to
future
which we send via the constructor and update thestate
based on that.
示例:
widget.future.then<void>((T data) {
if (_activeCallbackIdentity == callbackIdentity) {
setState(() {
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
});
}
}, onError: (Object error) {
if (_activeCallbackIdentity == callbackIdentity) {
setState(() {
_snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error);
});
}
});
所以 FutureBuilder
是我们通常所做的包装器/样板,因此不应该有任何性能影响.
So the FutureBuilder
is a wrapper/boilerplate of what we do typically, hence there should not be any performance impact.
这篇关于我什么时候应该使用 FutureBuilder?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!