StatefulWidget: vad det är, livscykel och arbetsprincip

Författare: IT Sectr Publicerad: 2026-07-01 Lästid: 9 min

StatefulWidget — en Flutter-widget med föränderligt tillstånd som gör att UI:t kan reagera på användaråtgärder, asynkrona händelser och dataströmmar. Enligt den officiella Flutter-dokumentationen (Flutter.dev, 2026) används StatefulWidget för alla interaktiva element i applikationen: inmatningsformulär, animationer, kryssrutor, växlar och skärmar som laddar data från nätverket. Till skillnad från StatelessWidget skapar den ett separat State-objekt som bevaras under hela livscykeln och kan återuppbyggas utan att återskapa själva widgeten.

Huvudpunkter

  • StatefulWidget — en widget som kan ändra sitt tillstånd under drift, vilket utlöser ombyggnad av UI via setState
  • Livscykel — StatefulWidget går igenom faserna createState, initState, didChangeDependencies, build, didUpdateWidget, dispose
  • State-objekt — ett separat objekt som lagrar tillståndet och existerar oberoende av widgeten under hela dess livstid
  • setState — det enda legitima sättet att meddela Flutter om behovet av att återuppbygga widgeten efter dataändring
  • Prestanda — överdriven användning av StatefulWidget ökar minnesförbrukningen och renderingstiden

Vad är StatefulWidget?

StatefulWidget — är en Flutter-klass som kan ändra sitt tillstånd som svar på användaråtgärder, systemhändelser eller asynkrona operationer. Till skillnad från StatelessWidget visas inte StatefulWidget direkt — den skapar ett State-objekt som ansvarar för rendering. Uppdelningen i två klasser (Widget och State) gör att Flutter kan återuppbygga UI utan att återskapa själva widgeten, vilket ger en betydande prestandafördel vid frekventa uppdateringar.

StatefulWidgets arkitektur följer mönstret «separering av föränderligt och oföränderligt»: själva widgeten förblir oföränderlig (som StatelessWidget), medan allt föränderligt tillstånd lagras i ett separat State-objekt. Detta gör att Flutter kan återanvända widgets genom att jämföra dem efter typ och Key, samtidigt som det aktuella tillståndet bevaras mellan ombyggnader.

Enligt Google (Flutter Architectural Overview, 2026) är StatefulWidget optimal för scenarier där tillståndet ändras mer än en gång under widgetens livstid: textfält, animationer, timers, dataströmmar, asynkron laddning. För engångsinitiering räcker StatelessWidget.

När är StatefulWidget nödvändig

StatefulWidget är obligatorisk när widgeten måste reagera på externa händelser: knapptryckning, slutförande av HTTP-förfrågan, datauppdatering från databas, prenumeration på WebSocket. Den är också nödvändig för widgets med animation, textfält med kontroller och komponenter som hanterar fokus. Om widgeten bara visar data och inte genererar händelser — använd StatelessWidget.

Intern struktur

StatefulWidget består av två klasser: själva StatefulWidget (lätt, oföränderlig) och State (tung, föränderlig). Ramverket skapar State via metoden createState(), som anropas en gång vid inplacering i trädet. State får en referens till widgeten via egenskapen widget och kan komma åt dess fält när som helst under livscykeln.

StatefulWidgets livscykel

StatefulWidgets livscykel består av sex huvudfaser, var och en tillhandahåller en överskrivningsbar metod för att utföra specifika uppgifter. Att förstå dessa faser är avgörande för korrekt arbete med resurser och för att undvika minnesläckor.

createState

createState — den första metoden i livscykeln, anropad när StatefulWidget placeras i trädet. Måste returnera en ny instans av State associerad med denna widget. Denna metod anropas exakt en gång under elementets hela livstid. Det är viktigt att inte utföra tunga operationer här — createState bör vara så lätt som möjligt.

initState

initState — anropas omedelbart efter att State skapats, före den första UI-konstruktionen. Här utförs: initiering av kontroller (TextEditingController, AnimationController), prenumeration på dataströmmar (StreamSubscription), inställning av timers och initial initiering av fält. Enligt Flutter-dokumentationen (Flutter.dev, 2026) kan BuildContext.of() inte anropas i initState — trädet är ännu inte fullt monterat.

didChangeDependencies

didChangeDependencies — anropas efter initState och varje gång InheritedWidget-beroenden ändras. Detta är lämplig plats för att anropa MediaQuery.of(context) eller prenumerera på Theme — värden som kan ändras under applikationens körning. Om widgeten använder InheritedWidget bör initieringslogiken vara här, inte i initState.

build och didUpdateWidget

build — huvudmetoden som returnerar widgetträdet. Anropas efter initState, efter didChangeDependencies och efter varje setState. didUpdateWidget anropas när föräldern återuppbygger och skickar StatefulWidget med nya parametrar. Här kan du jämföra gamla och nya widgetfält och vid behov uppdatera tillståndet.

dispose

dispose — den sista fasen i livscykeln. Här frigörs alla resurser: avprenumeration från strömmar, borttagning av kontroller, annullering av timers. Att inte anropa dispose leder till minnesläckor. Efter dispose anses State vara död — att anropa setState inuti det kastar ett undantag.

Hur fungerar StatefulWidget?

Mekanismen för hur StatefulWidget fungerar är baserad på det koordinerade arbetet av tre enheter: Widget (lätt beskrivning), Element (mellanlager) och State (datalager). När Flutter stöter på en StatefulWidget i beskrivningen skapar den ett StatefulElement som anropar createState och lagrar referensen till State-objektet. Vid förälderns ombyggnad jämför Flutter den nya widgeten med det aktuella Elementet — om typen och Key överensstämmer uppdateras Elementet medan State förblir detsamma.

Tillståndet ändras endast genom anrop av setState, som meddelar ramverket om behovet av ombyggnad. Det är viktigt att förstå: setState ändrar inte tillståndet automatiskt — det markerar bara widgeten som «smut sig». Utvecklaren uppdaterar själv State-fälten i callbacken som skickas till setState. Efter att callbacken slutförts anropar Flutter build och uppdaterar UI:t.

Enligt Dart/Flutter-teamet (Dart Language Specification, 2026) garanterar denna separation att alla tillståndsändringar sker synkront före anropet av build, vilket eliminerar situationen där UI:t visar delvis uppdaterad data. Detta är nyckelmekanismen för gränssnittskonsistens i Flutter.

Kodexempel i Dart

Låt oss titta på en enkel StatefulWidget — en knappklicksräknare. Den visar grundmönstret: skapande av State, initiering av fält i initState, ändring via setState:

dart
class CounterScreen extends StatefulWidget {
  const CounterScreen({super.key});

  @override
  State<CounterScreen> createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Antal: $_count'),
        ElevatedButton(
          onPressed: _increment,
          child: const Text('Öka'),
        ),
      ],
    );
  }
}

Exempel med asynkron dataladdning och livscykelhantering. StatefulWidget laddar data från nätverket och visar laddningsstatus:

dart
class UserProfilePage extends StatefulWidget {
  final String userId;
  const UserProfilePage({super.key, required this.userId});

  @override
  State<UserProfilePage> createState() => _UserProfilePageState();
}

class _UserProfilePageState extends State<UserProfilePage> {
  UserModel? _user;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadUser();
  }

  Future<void> _loadUser() async {
    final user = await UserService.fetchUser(widget.userId);
    setState(() {
      _user = user;
      _isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) return const CircularProgressIndicator();
    return Text('Hej, ${_user!.name}');
  }
}

I det andra exemplet är det viktigt att notera: initState startar en asynkron operation, men metoden själv är inte asynkron. Asynkroniciteten realiseras via async/await inuti den separata metoden _loadUser, som uppdaterar tillståndet via setState efter att förfrågan slutförts. Detta tillvägagångssätt garanterar att widgeten korrekt visar laddningsindikatorn innan den tar emot data.

StatefulWidget vs StatelessWidget

Valet mellan StatefulWidget och StatelessWidget är inte bara en fråga om att ha tillstånd. StatefulWidget erbjuder en fullständig livscykel med metoderna initState, didChangeDependencies, didUpdateWidget och dispose, vilket är nödvändigt för att arbeta med kontroller, animationer och strömmar. StatelessWidget har å sin sida inte dessa metoder och är alltid lättare för ramverket.

Rekommendation från Flutter-teamet (Flutter docs, 2026) — minimera antalet StatefulWidget i applikationen genom att lyfta tillståndet uppåt i trädet (State Hoisting) eller använda lösningar för tillståndshantering (Riverpod, Bloc, Provider). Varje StatefulWidget skapar ett State-objekt som lever tills elementet tas bort — ju fler sådana widgets, desto högre minnesbelastning.

KriteriumStatefulWidgetStatelessWidget
TillståndFöränderligtOföränderligt
Livscykel6 faserEndast build
State-objektSkapas separatKrävs inte
setStateTillgängligEj tillgänglig
PrenumerationerinitState/disposeStöds inte
const-konstruktorBegränsadFullt stödd
MinnesförbrukningHögreLägre

Prestanda och optimering

StatefulWidget kräver mer resurser än StatelessWidget på grund av behovet av att skapa och underhålla State-objektet. Men korrekt användning av StatefulWidget leder inte till prestandaproblem om några regler följs. För det första, undvik djup nästling av StatefulWidget — varje nivå lägger till overhead för trädgenomgång. För det andra, dela upp komplex StatefulWidget i flera enkla widgets, var och en ansvarig för sin del av tillståndet.

Enligt Flutter Performance-forskning (Flutter.dev, februari 2026) är den vanligaste orsaken till FPS-fall anrop av setState i föräldrawidgeten som återbygger alla ättlingar, inklusive StatelessWidget som inte har ändrat sin visning. Lösningen — flytta den föränderliga delen av UI:t till en separat StatefulWidget, så att setState bara återbygger minimum av nödvändiga widgets.

Användning av const inuti State är en annan viktig teknik. Om underordnade widgets deklareras som const kommer Flutter inte att återbygga dem vid anrop av setState i föräldern. Detta minskar ramverkets belastning och förkortar bildrutans renderingstid.

Undvik frekventa setState

Varje anrop av setState utlöser en fullständig ombyggnad av widgeten. Om tillståndet ändras med hög frekvens (till exempel animation eller dataström), överväg att använda AnimatedBuilder, ValueListenableBuilder eller StreamBuilder istället för manuella setState-anrop. Dessa widgets optimerar ombyggnaden och uppdaterar bara den del av UI:t som faktiskt har ändrats.

Vanliga misstag

Det första vanliga misstaget med StatefulWidget — att anropa setState efter dispose. När widgeten tas bort från trädet anses State vara död och varje setState-anrop kastar undantaget «setState called after dispose». Oftast händer detta när en asynkron operation slutförs efter att widgeten tagits bort. Lösningen — kontrollera mounted-flaggan före setState-anrop eller annullera asynkrona operationer i dispose.

Det andra misstaget — att utföra tunga beräkningar i build-metoden. Eftersom build anropas vid varje setState och varje ombyggnad av föräldern, bör alla beräkningar vara så lätta som möjligt. Om du behöver utföra en resurskrävande operation — flytta den till en separat Isolate eller cachelagra resultatet i ett State-fält.

Det tredje misstaget — att inte anropa super.initState() och super.dispose(). När dessa metoder överskrivs är utvecklaren skyldig att anropa föräldraimplementeringen. Om detta inte görs kan ramverket inte hantera Elementets tillstånd korrekt, vilket leder till svåra att hitta buggar.

Rekommendationer för att undvika misstag

  • Kontrollera alltid mounted före setState i asynkrona callbacks
  • Glöm inte att anropa super.initState() och super.dispose()
  • Gör inte HTTP-förfrågningar direkt i build — använd initState
  • Avsluta alla prenumerationer i dispose
  • Använd lägsta antal StatefulWidget i projektet

Vanliga frågor

Vad skiljer StatefulWidget från StatelessWidget?

StatefulWidget kan ändra sitt tillstånd via setState, har en livscykel (initState, dispose) och skapar ett separat State-objekt. StatelessWidget kan inte ändra tillstånd och har inga livscykelmetoder — den visar bara mottagna data.

Hur många gånger anropas createState?

createState anropas exakt en gång för varje instans av StatefulElement. Även om föräldern återbygger flera gånger, så länge widgetens typ och Key inte ändras, anropas inte createState — det befintliga State-objektet används.

Vad händer om dispose inte anropas?

Resurser frigörs inte: kontroller fortsätter att arbeta i bakgrunden, strömabonnemang förblir aktiva, timers annulleras inte. Detta leder till minnesläckor och kan orsaka setState-anrop efter dispose, vilket kastar ett undantag.

Kan StatefulWidget vara const?

Ja, konstruktorn för StatefulWidget kan vara const. Detta ger dock inte samma fördel som för StatelessWidget — State-objektet kommer ändå att skapas vid första inplaceringen. const påverkar bara själva widgeten (den lätta omslaget), inte State.

Vad används metoden didUpdateWidget för?

didUpdateWidget anropas när föräldern skickar StatefulWidget med nya parametrar. Detta behövs för att synkronisera tillståndet med ny data — till exempel om userId ändras i parametrarna måste den nya användarens profil laddas.

Sammanfattning

  • StatefulWidget — en widget med föränderligt tillstånd som använder ett separat State-objekt för datalagring och livscykelhantering
  • Livscykeln består av createState, initState, didChangeDependencies, build, didUpdateWidget och dispose, var och en med sitt syfte
  • setState — det enda legitima sättet att meddela ramverket om tillståndsändring, varefter build automatiskt anropas
  • mounted — en flagga som måste kontrolleras före setState i asynkrona operationer för att undvika undantag efter dispose
  • Prestanda — StatefulWidget kräver mer resurser än StatelessWidget; det rekommenderas att minimera antalet genom att flytta tillstånd till externa lager
  • const underordnade widgets inuti State gör det möjligt att minska omfattningen av ombyggnad vid setState-anrop, vilket förbättrar prestanda
  • Korrekt val — använd StatefulWidget endast när widgeten behöver hantera föränderlig data eller asynkrona operationer

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.

Diskutera projektet

Läs också