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:
- Have two state variables,
dataFromBackend
and isLoadingFlag
- On launch, set
isLoadingFlag = true
, and based on this, show loader
.
- Once data arrives, set data with what you get from backend and set
isLoadingFlag = false
(inside setState
obviously)
- We need to have a
if-else
in widget creation. If isLoadingFlag
is true
, show the loader
else show the data
. On failure, show error message.
Tasks for FutureBuilder:
- 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
Pros of FutureBuilder
- Does not use the two state variables and
setState
- Reactive programming (
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.
- FutureBuilder is just a
StatefulWidget
whose state
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 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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…