问题
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.
dataFromBackend2.isLoadingFlag - On launch, set
isLoadingFlag = trueand based on which showloader. - Once data arrival, set data with what you get from
backendand setisLoadingFlag = false(insidesetStateobviously) - We need to have a
if-elseinwidgetcreation. IfisLoadingFlagistrue, showloaderelse show thedata. If failure, showerror message.
Tasks for FutureBuilder:
- give the async task in
futureof Future Builder - based on
connectionState, showmessage(loading,active(streams),done) - based on
data(snapshot.hasError)show view
Pros of FutureBuilder
- no
two flagsand nosetState - reactive programming (
FutureBuilderwill 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
StatefulWidgetwhosestatevariable is_snapshot - Intial state is
_snapshot = new AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData); It is subscribing to
futurewhich we send in constructor and updating thestatebased 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