What are the common pitfalls of using FutureBuilder?
Short Answer
The most common FutureBuilder bug is passing a new Future instance on every build (e.g. calling a function directly in the future: parameter), which re-triggers the loading state on every rebuild instead of just once.
FutureBuilder re-runs its builder whenever the widget rebuilds, but only actually re-fetches if the future instance it's given is a different Future than last time. Writing future: fetchData() directly inside build() creates a brand-new Future object on every rebuild — even ones triggered by unrelated state changes — causing the UI to flash back to a loading spinner repeatedly.
The fix is to create the Future once (in initState, or a stored state variable) and pass that same stored reference into future: on every build. This is conceptually the same fix as a common useEffect dependency-array mistake in React.
Code Example
class _MyWidgetState extends State<MyWidget> {
late final Future<Data> _future = fetchData(); // created once
@override
Widget build(BuildContext context) {
return FutureBuilder<Data>(
future: _future, // stable reference across rebuilds
builder: (context, snapshot) { /* ... */ return const SizedBox(); },
);
}
}Common Mistakes
- ×Calling the async function directly inside the future: parameter on every build.
- ×Not handling ConnectionState.none/waiting/done explicitly, leading to a flash of incorrect UI between states.
Interview Tips
- →This is a commonly-asked 'gotcha' — mentioning the new-Future-per-build issue signals real hands-on debugging experience.