FutureBuilder — är en widget i Flutter som automatiskt bygger om sitt gränssnitt baserat på det aktuella tillståndet för AsyncSnapshot som hämtas från det överförda Future. Till skillnad från manuell anropning av setState efter await, erbjuder FutureBuilder ett deklarativt tillvägagångssätt: den prenumererar på Future vid första renderingen och anropar builder-funktionen vid varje tillståndsändring — laddning, fel eller redo data. Enligt Flutter API Reference (2026) är FutureBuilder särskilt användbar för att ladda data från nätverk, läsa från databas och alla asynkrona operationer där UI måste visa en laddningsindikator, felmeddelande eller redo innehåll.
Huvudpunkter
FutureBuilder — är en inbyggd Flutter-widget från widgets-paketet som tar emot Future<T> och en builder-funktion. När Future-tillståndet ändras (körs, slutfört med data, slutfört med fel) bygger FutureBuilder automatiskt om UI genom att anropa builder med en ny AsyncSnapshot. Detta eliminerar behovet av manuell hantering av laddningstillstånd via setState och flaggor.
Till skillnad från StreamBuilder som arbetar med dataströmmar (Stream), är FutureBuilder avsedd för engångs asynkrona operationer: HTTP-förfrågan, läsning från fil, databasfråga. FutureBuilder hanterar själv prenumerationen på Future: vid första bygget startar den Future och följer dess slutförande. När widgeten förstörs avbryter FutureBuilder inte Future — detta är utvecklarens ansvar.
Enligt Flutter Cookbook (2026) rekommenderas FutureBuilder för fall där den asynkrona operationen körs en gång vid skärminitialisering. För upprepade operationer eller dataströmmar, använd StreamBuilder. Båda widgetarna följer samma Reactive UI-mönster, men FutureBuilder är optimerad för engångsförfrågningar.
Den interna implementeringen av FutureBuilder prenumererar på Future via Future.then och catchError. Vid start ställer FutureBuilder in connectionState till ConnectionState.waiting och anropar builder med tomma data. Vid lyckad slutförande ändras connectionState till ConnectionState.done med data. Vid fel fylls snapshot.error med felobjektet. Varje ändring utlöser ombyggnad av widgeten.
AsyncSnapshot — är ett containerobjekt som FutureBuilder skickar till builder-funktionen vid varje tillståndsändring. Det innehåller all information om den aktuella statusen för den asynkrona operationen: om laddning pågår, vilka data som har tagits emot, om ett fel har inträffat. Att förstå AsyncSnapshot är nyckeln till korrekt UI-bygge med FutureBuilder.
| Egenskap | Typ | Beskrivning |
|---|---|---|
| connectionState | ConnectionState | Aktuell anslutningsstatus (none, waiting, active, done) |
| data | T? | Data som tagits emot från Future (null tills slutförande eller vid fel) |
| error | Object? | Felobjekt om Future slutfördes med ett undantag |
| hasData | bool | true om data inte är null och tillståndet är ConnectionState.done |
| hasError | bool | true om Future slutfördes med ett fel |
Enum ConnectionState bestämmer fasen för den asynkrona operationen. None — initialt tillstånd när Future ännu inte har startats (används sällan, vanligtvis vid första bygget utan initialData). Waiting — Future körs, data har ännu inte tagits emot. Active — används endast av StreamBuilder för strömmar med partiella data. Done — Future är slutförd, data är tillgängliga via snapshot.data eller fel via snapshot.error.
Korrekt hantering av alla AsyncSnapshot-tillstånd i builder-funktionen är ett obligatoriskt krav för produktionskod. Om du inte hanterar waiting-tillståndet kommer användaren att se en tom skärm under laddning. Om du inte hanterar hasError kommer användaren att få ett Exception utan förklaring. Rekommenderat mönster: kontrollera hasError → kontrollera hasData → visa som standard laddning.
FutureBuilder kan användas i flera standardmönster, var och en löser en specifik uppgift. Låt oss titta på huvudsakliga scenarier: ladda data vid initialisering, ladda med cache, parallella förfrågningar och felhantering med omförsök.
Det vanligaste mönstret — FutureBuilder i build-metoden för StatefulWidget eller StatelessWidget. Future skickas från initState eller skapas direkt i build. Det är viktigt att inte skapa Future i build-metoden vid varje ombyggnad — detta leder till upprepade förfrågningar. Använd Future som sparats i State-fältet.
För att förhindra upprepade förfrågningar kan FutureBuilder kombineras med CachedNetworkImage eller lokal cache. Efter första laddningen sparas data i minnet eller SharedPreferences, och FutureBuilder visar cachad data omedelbart, samtidigt som den uppdaterar den från nätverket. Detta förbättrar UX genom omedelbar respons.
Enligt pub.dev (2026) är cachning särskilt relevant för bilder och datalistor. FutureBuilder med CachedNetworkImageProvider visar automatiskt den cachade bilden, och vid dess frånvaro — en laddningsindikator med efterföljande visning av den nedladdade filen.
FutureBuilder och manuell tillståndshantering via setState — två tillvägagångssätt för asynkront UI i Flutter. Varje har sina fördelar och begränsningar. Valet beror på skärmens komplexitet och antalet asynkrona operationer.
FutureBuilder vinner i enkelhet: du behöver inte deklarera fält för laddningstillstånd, data och fel — allt hanteras via AsyncSnapshot. Den är idealisk för enkla skärmar med en asynkron operation (en HTTP-förfrågan, databasläsning). Men med 5+ asynkrona operationer på en skärm skapar FutureBuilder överdriven nästling — en ”pyramid” av nästlade FutureBuilders bildas.
setState med manuella tillståndsflaggor ger mer kontroll och läsbarhet i komplex logik. För skärmar med flera beroende förfrågningar (ladda användare → ladda hans beställningar → ladda beställningsdetaljer) är det bättre att använda setState med ChangeNotifier eller Bloc. Enligt Flutter State Management Guide (2026), för komplexa scenarier rekommenderas att använda Riverpod eller Bloc istället för FutureBuilder, eftersom de ger bättre separation av logik och presentation.
Låt oss titta på ett praktiskt exempel på FutureBuilder för att ladda en användarlista från ett REST API. Koden visar korrekt hantering av alla tre AsyncSnapshot-tillstånd: laddning, fel och redo data.
class UserListPage extends StatefulWidget {
const UserListPage({super.key});
@override
State<UserListPage> createState() => _UserListPageState();
}
class _UserListPageState extends State<UserListPage> {
final Future<List<User>> usersFuture = UserRepository().fetchUsers();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Users')),
body: FutureBuilder<List<User>>(
future: usersFuture,
builder: (context, AsyncSnapshot<List<User>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error_outline, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text('Error: ${snapshot.error}'),
],
),
);
}
if (snapshot.hasData) {
final users = snapshot.data!;
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(backgroundImage: NetworkImage(users[index].avatarUrl)),
title: Text(users[index].name),
subtitle: Text(users[index].email),
);
},
);
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}
I exemplet hanterar FutureBuilder alla tre tillstånd. Vid fel visas en ikon med felmeddelande. Vid lyckad laddning — ListView med avatarer och namn. Under laddning — CircularProgressIndicator. Future är deklarerad som ett klassfält, vilket förhindrar återanrop vid ombyggnad. Detta mönster täcker 90% av användningsscenarierna för FutureBuilder i mobila applikationer.
Vanliga frågor
FutureBuilder anropar builder vid varje tillståndsändring av Future: första gången vid skapande (connectionState: none eller waiting), andra gången vid slutförande (connectionState: done). Om den överordnade widgeten byggs om, byggs FutureBuilder också om. För att förhindra upprepade anrop, se till att Future skapas utanför build-metoden — annars skapar varje build-anrop ett nytt Future.
Spara Future i StatefulWidgets fält (i initState) eller använd memoization. Om Future skapas inuti build-metoden kommer varje build-anrop att skapa ett nytt Future, och FutureBuilder kommer att starta om den asynkrona operationen. För StatelessWidget, använd paketet cached_future eller keep-alive-widgets så att Future körs en gång oavsett ombyggnader.
FutureBuilder är avsedd för engångs asynkrona operationer (en HTTP-förfrågan, en databasläsning). StreamBuilder arbetar med dataströmmar som kan emittera flera värden över tid (chatt, prisuppdateringar, geolokalisering). StreamBuilder stödjer ConnectionState.active för partiella data, medan FutureBuilder endast stödjer waiting och done.
För flera parallella Futures, använd Future.wait och skicka resultatet till en FutureBuilder. Future.wait accepterar en lista av Futures och returnerar Future<List> — när alla Futures är slutförda får builder en array av resultat. För sekventiella förfrågningar, använd en kedja av Future.then inuti ett enda Future eller nästlade FutureBuilders (mindre läsbart). Alternativ — paketet riverpod med AsyncValue för flera asynkrona tillstånd.
FutureBuilder avbryter inte Future automatiskt. För avbrytning, använd CancelableOperation från async-paketet eller en egen mekanism via en cancelled-flagga i State. I dispose() ställ in flaggan, och efter Future slutförande kontrollera den innan du anropar setState. Alternativt, använd paketet riverpod med AutoDispose som automatiskt avbryter asynkrona operationer när du lämnar skärmen.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också