I would like to know when to use a FutureBuilder and how is it usefull, given the fact that a widget can be built multiple times during its life time and not only when we setState or update it, so instead of using below code:
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool done = false;
@override
void initState() {
wait();
super.initState();
}
Future<void> wait() async {
await Future.delayed(Duration(seconds: 2));
setState(() {
done = true;
});
}
@override
Widget build(BuildContext context) {
print('is built');
return done ? Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
) : Scaffold(body: CircularProgressIndicator(),);
}
}
In which cases would a FutureBuilder work for me instead of the above set up, given the fact that I would also want to optimize my app for less backend reads (in FutureBuilder I would read more than once). I am looking for a case where FutureBuilder would be more usefull and correct than the above setup.
Why FutureBuilder Called again? This is due to state changes that come if setState() called, which triggers build() method, and due to this inside widgets will be re-initialize again.
A Snapshot simplifies accessing and converting properties in a JSON-like object, for example a JSON object returned from a REST-api service.
ListView is a very important widget in a flutter. It is used to create the list of children But when we want to create a list recursively without writing code again and again then ListView. builder is used instead of ListView. ListView. builder creates a scrollable, linear array of widgets.
FutureBuilder
is used to handle "asynchronous" calls that return the data you want to display.
For example, let's say we have to get a List<String>
from the server.
The API call :
Future<List<String>> getStringList() async {
try {
return Future.delayed(Duration(seconds: 1)).then(
(value) => ['data1', 'data2', 'data3', 'data4'],
);
} catch (e) {
throw Exception(e);
}
}
How can we handle the above API call status (load, data, error...etc) using FutureBuilder
:
FutureBuilder<List<String>?>(
future: getStringList(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.done:
if (snapshot.hasError)
return Text(snapshot.error.toString());
else
return ListView(
children: snapshot.data!.map((e) => Text(e)).toList(),
);
default:
return Text('Unhandle State');
}
},
),
As we can see, we don't have to create a state class with variable isLoading
bool
and String
for error...etc. FutureBuilder
saves us time.
BUT
Since FutureBuilder
is a widget and lives in the widget tree, rebuilding can make FutureBuilder
run again.
So I would say you can use FutureBuilder
when you know there won't be a rebuild, however there are many ways (in the internet) to prevent FutureBuilder
from being called again when the rebuild happens but it didn't work for me and leads to unexpected behavior.
Honestly I prefer handling the state in a different class with any state management solution than using FutureBuilder
because it would be safer (rebuild wont effect it), more usable and easier to read (spreating business logic from UI).
FutureBuilder
Widget that builds itself based on the latest snapshot of interaction with a Future.
The future must have been obtained earlier, e.g. during State.initState, State.didUpdateWidget, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder.
If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.A general guideline is to assume that every build method could get called every frame, and to treat omitted calls as an optimization.
Documentation is very great way to get started and understand what widget does what in what condition...
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With