问题
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?
Hope it's clear enough!
回答1:
FutureBuilder
removes some of the boilerplate codes.
Lets say you want to fetch data from backend
on launch of page and show loader till data comes.
Tasks for ListBuilder:
- have two state variables 1.
dataFromBackend
2.isLoadingFlag
- On launch, set
isLoadingFlag = true
and based on which showloader
. - Once data arrival, set data with what you get from
backend
and setisLoadingFlag = false
(insidesetState
obviously) - We need to have a
if-else
inwidget
creation. IfisLoadingFlag
istrue
, showloader
else show thedata
. If failure, showerror message
.
Tasks for FutureBuilder:
- give the async task in
future
of Future Builder - based on
connectionState
, showmessage
(loading
,active(streams)
,done
) - based on
data(snapshot.hasError)
show view
Pros of FutureBuilder
- no
two flags
and nosetState
- reactive programming (
FutureBuilder
will take care of updating the view on data arrival)
Example:
new FutureBuilder<String>(
future: _fetchNetworkCall, // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Text('Loading....');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text('Result: ${snapshot.data}');
}
},
)
Performance impact:
I just looked into the FutureBuilder
code to understand the performance impact of using this.
- FutureBuilder is just a
StatefulWidget
whosestate
variable is_snapshot
- Intial state is
_snapshot = new AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);
It is subscribing to
future
which we send in constructor and updating thestate
based on that.widget.future.then<void>((T data) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = new AsyncSnapshot<T>.withData(ConnectionState.done, data); }); } }, onError: (Object error) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = new AsyncSnapshot<T>.withError(ConnectionState.done, error); }); } });
So the FutureBuilder
is a wrapper/boilerplate of what we do typically. So there should not be any performance impact.
来源:https://stackoverflow.com/questions/51983011/flutter-future-builder-when-should-i-use-it