tezvyn:

Explain FutureBuilder and how it manages async UI states

AI-drafted, machine-checkedSource: api.flutter.devbeginner

This tests declarative async UI state management. Obtain the Future before build, pass it to FutureBuilder, and branch on snapshot.connectionState and hasError to render loading, data, or error states.

WHAT THIS TESTS: Declarative async state management in Flutter. Specifically, whether you know how to bind a Future to the widget tree without imperative setState boilerplate, and whether you understand the AsyncSnapshot lifecycle and builder contract.

A GOOD ANSWER COVERS: Four things in order. First, Future acquisition timing: the Future must be obtained earlier than build, such as in State.initState, State.didUpdateWidget, or State.didChangeDependencies, and must never be created inside the build method. Second, the builder callback signature and snapshot states: the builder receives an AsyncSnapshot and should branch on snapshot.connectionState, handling ConnectionState.waiting with a loading indicator, ConnectionState.done with either data or error UI, and optionally ConnectionState.none. Third, error handling: after checking state is done, inspect snapshot.hasError or snapshot.error to render an error widget rather than data. Fourth, the role of initialData: it seeds the snapshot before the future completes, preventing null default flicker or layout shifts.

COMMON WRONG ANSWERS: Creating the Future inside the build method is the most common and serious mistake; because build can run every frame, this restarts the async work repeatedly and wastes resources. Another red flag is calling setState manually around a Future instead of using FutureBuilder, which shows the candidate does not understand Flutter's declarative patterns. A third mistake is ignoring the ConnectionState.waiting state and only checking hasData, which can cause a blank frame or jank while waiting.

LIKELY FOLLOW-UPS: How would you refresh or retry the Future? The correct pattern is to store the Future in state and rebuild with a new Future instance. What is the difference between FutureBuilder and StreamBuilder? FutureBuilder is equivalent to a StreamBuilder wired to future.asStream, except it never emits ConnectionState.active snapshots. How do you handle a Future that is already completed when passed in? The builder will still see one frame of ConnectionState.waiting because there is no way to synchronously detect completion, then immediately transition to done.

ONE CONCRETE EXAMPLE: Imagine a profile page fetching user data. In initState, you assign _userFuture = api.fetchUser(id). In build, you return FutureBuilder with future set to _userFuture and a builder that checks snapshot.connectionState. If waiting, return CircularProgressIndicator. If done and hasError, return Text showing snapshot.error. If done and hasData, return UserProfileView with the data. Otherwise return an empty SizedBox. This keeps the async work stable across rebuilds and cleanly maps each snapshot state to a distinct widget.

Read the original → api.flutter.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.