State — det centrala objektet för datahantering i Flutter, associerat med StatefulWidget och ansvarigt för att lagra föränderlig information och bygga gränssnittet. Enligt officiella Flutter-dokumentationen (Flutter.dev, 2026) finns State under hela widgetens livscykel och överlever dess ombyggnationer, vilket säkerställer datakonsistens mellan UI-uppdateringar. Till skillnad från själva widgeten kan State ändra sina fält och initiera ombyggnation genom att anropa setState.
Huvudpunkter
State — är ett objekt i Flutter-arkitekturen som lagrar StatefulWidgets föränderliga data och bestämmer hur dessa data visas i gränssnittet. Varje StatefulWidget skapar vid inbäddning i trädet exakt ett State-objekt genom metoden createState. State existerar oberoende av widgeten: om föräldern bygger om StatefulWidget med nya parametrar, förblir State densamma och tar emot den uppdaterade widgeten via egenskapen widget.
Enligt Flutter Architectural Overview (Google, 2026) är separationen av Widget och State ett medvetet arkitektoniskt beslut som gör det möjligt för ramverket att återanvända trädelement. Widgeten (lätt beskrivning) kan skapas och förstöras flera gånger, men State (tungt objekt med data) finns kvar i minnet så länge elementet är i trädet. Detta förhindrar dataförlust vid frekventa ombyggnationer av föräldrawidgets.
State implementerar gränssnittet StatefulWidget via en generik: class _MyState extends State<MyWidget>. Generiken binder State till en specifik StatefulWidget-typ och ger typsäker åtkomst till dess fält via egenskapen widget.
State-objektet lagras i StatefulElement — det mellanliggande lagret mellan Widget och RenderObject. StatefulElement skapar State via createState, behåller referensen till det och överför State som ägare. Elementet förstörs endast när widgeten tas bort från trädet — fram till dess lever State i minnet.
Livscykeln för State är deterministisk och består av en strikt sekvens av anrop. Att förstå denna sekvens är grunden för korrekt arbete med resurser och förhindrande av minnesläckor.
initState anropas först när State skapas. I denna metod initieras kontroller, prenumerationer på dataströmmar, timers och initiala värden för fält. Att anropa super.initState() på första raden är obligatoriskt. I initState-fasen är widgetträdet ännu inte fullt monterat, så metoder som MediaQuery.of(context) kan fungera felaktigt.
didChangeDependencies anropas efter initState och vid varje ändring av InheritedWidget-beroenden. Just här, inte i initState, bör MediaQuery.of(context) eller Theme.of(context) anropas, eftersom trädet vid denna tidpunkt redan är monterat. Denna metod anropas också om widgeten flyttas till en annan kontext där InheritedWidget ger andra värden.
build — States huvudmetod som returnerar widgetträdet. Anropas efter initState, efter didChangeDependencies och efter varje setState. Metoden build bör inte ha sidoeffekter — den beskriver bara gränssnittet baserat på aktuella värden för States fält.
didUpdateWidget anropas när föräldern bygger om StatefulWidget med nya parametrar. State får tillgång till den gamla widgeten via oldWidget och kan jämföra den med den nya. Om parametrarna har ändrats kan tillståndet uppdateras, ny data laddas eller animeringen startas om.
dispose — den avslutande metoden där alla resurser frigörs: kontroller, prenumerationer, timers. Efter dispose markeras State som död: mounted returnerar false, ett anrop av setState kastar ett undantag. Att anropa super.dispose() på metodens sista rad är obligatoriskt.
| Metod | När anropas | Obligatorisk super |
|---|---|---|
| initState | När State skapas | Ja, på första raden |
| didChangeDependencies | Efter initState och vid InheritedWidget-förändring | Ja |
| build | Efter initState, didChangeDependencies, setState | Nej |
| didUpdateWidget | Vid ny widget från förälder | Ja |
| setState | Vid anrop av utvecklaren | Nej |
| dispose | Vid borttagning från trädet | Ja, på sista raden |
Mekanismen för State bygger på tre nyckelprinciper: association med Element, reaktivitet via setState och åtkomst till föräldern via egenskapen widget. När Flutter bygger elementträdet och stöter på StatefulElement, anropar det createState för den associerade widgeten. Det skapade State lagras i elementet och finns kvar tills elementet tas bort.
När setState anropas markerar State sig själv som ”irty” och schemalägger ombyggnation för nästa bildruta. Viktigt: setState anropar inte build omedelbart — det registrerar bara behovet av ombyggnation. Flutter samlar alla dirty-element i den aktuella bildrutan och bygger om dem i batch, vilket optimerar prestandan. Efter build-anropet återgår State till ”clean”-tillstånd.
Egenskapen widget låter State läsa parametrarna som skickats till StatefulWidget-konstruktorn. Eftersom StatefulWidget är oföränderlig (som StatelessWidget) ändras dess fält inte — när parametrar ändras skapar föräldern en ny widget och State tar emot den via didUpdateWidget. Detta garanterar att State alltid arbetar med aktuell data från föräldern.
Grundläggande exempel på State med ett fält som ändras av en timer. Demonstrerar initState, setState och dispose:
class _TimerWidgetState extends State<TimerWidget> {
int _seconds = 0;
Timer? _timer;
@override
void initState() {
super.initState();
_timer = Timer.periodic(
const Duration(seconds: 1),
(_) => setState(() => _seconds++),
);
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Text('$_seconds sekunder har gått');
}
}
Exempel på användning av egenskapen widget för åtkomst till förälderns parametrar och reaktion på deras förändringar via didUpdateWidget:
class _GreetingState extends State<GreetingWidget> {
String _displayName = '';
@override
void initState() {
super.initState();
_displayName = _formatName(widget.name);
}
@override
void didUpdateWidget(GreetingWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.name != oldWidget.name) {
setState(() {
_displayName = _formatName(widget.name);
});
}
}
String _formatName(String name) => name.trim().isEmpty ? 'Guest' : name;
@override
Widget build(BuildContext context) {
return Text('Hej, $_displayName!');
}
}
I det andra exemplet övervakar State ändringen av ingångsparametern name och omformaterar visningen endast vid verklig ändring. Utan kontrollen widget.name != oldWidget.name skulle metoden anropas vid varje ombyggnation av föräldern, även om namnet inte ändrades — onödigt arbete för ramverket.
State och StatefulWidget är två olika klasser i Flutter-arkitekturen med olika roller. StatefulWidget är ett lätt oföränderligt omslag som beskriver widgetens konfiguration och skapar State. State är ett tungt objekt som lagrar föränderlig data, hanterar prenumerationer och bygger UI. Denna separation gör att Flutter kan förstöra och skapa widgets utan att förlora tillstånd.
Alla fält i StatefulWidget måste vara final och anges i konstruktorn — de ändras inte efter skapande. State däremot kan ändra sina fält när som helst, men alla ändringar måste föregås av ett anrop till setState, så att Flutter får reda på behovet av ombyggnation. Detta är den viktigaste skillnaden: StatefulWidget är ”vad som ska visas”, State — ”hur det ska visas och vilken data som ska användas”.
Enligt Flutter source code analysis (Flutter SDK, 2026) innehåller StatefulWidget bara ett obligatoriskt fält — createState, medan State har tillgång till BuildContext, kan prenumerera på strömmar, hantera animationer och kontroller. Det rekommenderas att hålla StatefulWidget så enkel som möjligt och flytta all logik till State.
Separationen av Widget och State är ett arkitektoniskt beslut som säkerställer konfigurationens oföränderlighet. Om StatefulWidget själv lagrade tillståndet skulle tillståndet gå förlorat vid varje ombyggnation av föräldern. Genom att flytta tillståndet till ett separat objekt garanterar Flutter att data överlever ombyggnationer och att widgets förblir lätta och jämförbara.
State-objektet är isolerat — det har ingen direkt åtkomst till andra widgets State. För datautbyte mellan widgets används InheritedWidget eller externa verktyg för tillståndshantering: Provider, Riverpod, Bloc, Redux. Varje metod löser problemet på sitt sätt: InheritedWidget arbetar via widgetträdet, Provider — via en DI-behållare, Bloc — via händelseströmmar.
Valet av verktyg beror på projektets omfattning. För en liten applikation räcker InheritedWidget och lokalt State. För medelstora och stora projekt rekommenderas Riverpod eller Bloc — de ger testbarhet, förutsägbarhet och separation av logik från UI. State används då endast för widgetens lokala data (fokus, rullning, animering).
Enligt Flutter Community Survey 2025 (Flutter Foundation, december 2025) är Riverpod den mest populära lösningen för tillståndshantering i nya projekt (38%), följt av Bloc (31%) och Provider (22%). Alla tre verktygen är kompatibla med State och kräver inte att man frångår den standardmässiga livscykeln.
Första misstaget — glömma att kontrollera mounted före setState i en asynkron återuppringning. När widgeten har tagits bort från trädet (t.ex. användaren lämnade skärmen), men den asynkrona operationen (HTTP-begäran) fortfarande körs, är State redan död efter dess slutförande. Att anropa setState i ett dött State kastar ett undantag. Kontrollen if (mounted) setState(...) löser problemet.
Andra misstaget — initiering av InheritedWidget-beroenden i initState istället för didChangeDependencies. I initState är kontexten ännu inte monterad, så MediaQuery.of(context) kommer att kasta ett undantag. Alla InheritedWidget-beroenden bör konfigureras i didChangeDependencies eller i build.
Tredje misstaget — mutering av fält utan att anropa setState. Om utvecklaren ändrar ett State-fält utan setState, får Flutter inte reda på ändringen och UI uppdateras inte. Till exempel: _list.add(item) utan efterföljande setState((){}) kommer att ändra listan, men skärmen förblir densamma.
Säkerhetsmönster för asynkrona operationer i State:
Future<void> _fetchData() async {
final data = await ApiService.fetch();
if (mounted) {
setState(() => _data = data);
}
}
Kontroll av mounted garanterar att setState endast anropas för ett levande State, vilket förhindrar undantaget ”setState called after dispose”.
Vanliga frågor
StatefulWidget är widgetens oföränderliga konfiguration, medan State är ett föränderligt objekt som lagrar data och hanterar livscykeln. Widgeten kan återskapas, State — inte. StatefulWidget skapar State via createState.
Exakt ett. Metoden createState anropas en gång vid första inbäddningen av StatefulWidget i trädet. Även om föräldern byggs om flera gånger förblir State-objektet detsamma, tills widgetens typ eller Key ändras.
mounted är en boolesk flagga som visar om State finns i widgetträdet. Efter anrop av dispose blir mounted false. Används för kontroll före setState i asynkrona återuppringningar för att undvika undantag.
Nej. State är alltid bundet till en specifik StatefulWidget via en generik: State<T extends StatefulWidget>. Att skapa State direkt, utan association med en widget, är arkitektoniskt omöjligt.
Ett undantag kastas: ”setState called after dispose”. Efter anrop av dispose anses State vara dödt och alla försök att bygga om UI via setState är förbjudna. Lösning — kontrollera mounted före varje setState.
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å