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!
FutureBuilder
removes boilerplate code.
Let's say you want to fetch some data from the backend on page launch and show a loader until data comes.
Tasks for ListBuilder:
dataFromBackend
and isLoadingFlag
isLoadingFlag = true
, and based on this, show loader
.isLoadingFlag = false
(inside setState
obviously)if-else
in widget creation. If isLoadingFlag
is true
, show the loader
else show the data
. On failure, show error message.Tasks for FutureBuilder:
future
of Future BuilderconnectionState
, show message (loading
, active(streams)
, done
)data(snapshot.hasError)
, show viewPros of FutureBuilder
setState
FutureBuilder
will take care of updating the view on data arrival)Example:
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}');
}
},
)
Performance impact:
I just looked into the FutureBuilder
code to understand the performance impact of using this.
StatefulWidget
whose state
variable is _snapshot
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);
future
which we send via the constructor and update the state
based on that.Example:
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);
});
}
});
So the FutureBuilder
is a wrapper/boilerplate of what we do typically, hence there should not be any performance impact.