FutureBuilder Called Multiple Times in Flutter – [Solved]
Almost every flutter developer face this problem when he works with FutureBuilder in Flutter. The problem is that FutureBuilder called multiple times. Let’s understand why FutureBuilder behaves like this.
Understand the problem
The repeated calls of Future occur when there are state changes induced by calling setState(). This causes the build() method to trigger, leading to the re-initialization of widgets within. So FutureBuilder rebuilds as well. For instance, if there’s a state change that causes the build method of the parent widget to run again. It can lead to the FutureBuilder being called multiple times, potentially initiating the asynchronous operation again.
Actually the problem doesn’t solely lie in the multiple calls of the FutureBuilder; rather, it’s rooted in the Future object repeatedly triggering events. The previous question encapsulates various aspects within the FutureBuilder but doesn’t address the core issue of the Future object continually firing events.
How to Fix FutureBuilder Called Multiple Times
The FutureBuilder, being a widget in your tree, triggers calls to future() whenever it rebuilds—like when there’s input in a TextField. It lacks awareness of whether that function has been called before or not.
To ensure it’s called only once, store the result in a state member and use it within your FutureBuilder. This keeps the data as long as that state persists in the widget tree.
For instance, you could set it in initState() to execute once per state lifecycle, or in didChangeDependencies() to refresh the call when a dependency changes.
class MoviesList extends State<MoviesList> {
late final Future myFuture;
@override
void initState() {
myFuture = getMovies();
}
@override
Widget build(BuildContext context) {
child: FutureBuilder(
future: myFuture,
)
}
}
Explain the solution
In this code, getMovies()
will not be called multiple times because of how it’s structured within the initState()
method of the MoviesList class.
The initState()
method is triggered only once during the lifecycle of a StatefulWidget. Here, myFuture is assigned the result of the getMovies() function call. As initState()
is invoked just once when the widget is initialized. And getMovies()
will execute only once to fetch the movies data, and the resulting future will be stored in myFuture.
Later, within the build()
method, the FutureBuilder utilizes myFuture as its future parameter. As myFuture already holds the future generated by the initial call to getMovies()
in initState(), it won’t cause multiple calls to getMovies()
each time the widget rebuilds. Instead, it will utilize the stored value within myFuture to handle the asynchronous behavior.
You can also read How to generate Signed apk in Flutter