State: Was es ist, Zustandsverwaltung und Funktionsprinzip

Autor: IT Sectr Veröffentlicht: 2026-07-01 Lesezeit: 9 Min.

State ist das zentrale Datenverwaltungsobjekt in Flutter, das mit StatefulWidget verbunden ist und für die Speicherung veränderlicher Informationen und den Aufbau der Benutzeroberfläche verantwortlich ist. Laut der offiziellen Flutter-Dokumentation (Flutter.dev, 2026) existiert State während des gesamten Widget-Lebenszyklus und überlebt dessen Neuerstellungen, wodurch Datenkonsistenz zwischen UI-Updates gewährleistet wird. Im Gegensatz zum Widget selbst kann State seine Felder ändern und über den setState-Aufruf eine Neuerstellung auslösen.

Wichtige Punkte

  • State — ein Objekt, das veränderliche Daten von StatefulWidget speichert und dessen Neuerstellung über setState verwaltet
  • Lebenszyklus — State durchläuft initState, didChangeDependencies, build, didUpdateWidget und dispose, jede Phase mit klarem Zweck
  • mounted — ein Flag, das anzeigt, dass State sich noch im Widget-Baum befindet und sicher setState aufrufen kann
  • widget — ein Verweis auf das zugehörige StatefulWidget, zugreifbar über die State-Eigenschaft zum Lesen der Elternparameter
  • Isolierung — State ist von anderen State isoliert; für den Datenaustausch werden InheritedWidget oder externe Zustandsverwaltungstools verwendet

Was ist State in Flutter?

State ist ein Objekt in der Flutter-Architektur, das veränderliche Daten eines StatefulWidget speichert und bestimmt, wie diese Daten in der Benutzeroberfläche angezeigt werden. Jedes StatefulWidget erstellt beim Einfügen in den Baum genau ein State-Objekt über die Methode createState. State existiert unabhängig vom Widget: Wenn das Elternteil das StatefulWidget mit neuen Parametern neu erstellt, bleibt State gleich und erhält das aktualisierte Widget über die Eigenschaft widget.

Laut der Flutter Architectural Overview (Google, 2026) ist die Trennung von Widget und State eine bewusste architektonische Entscheidung, die es dem Framework ermöglicht, Baumelemente wiederzuverwenden. Das Widget (eine leichte Beschreibung) kann mehrmals erstellt und zerstört werden, aber State (ein schweres Objekt mit Daten) bleibt im Speicher, solange das Element im Baum ist. Dies verhindert Datenverlust bei häufigen Neuerstellungen von Eltern-Widgets.

State implementiert die Schnittstelle StatefulWidget über Generika: class _MyState extends State<MyWidget>. Das Generikum bindet State an einen bestimmten StatefulWidget-Typ und bietet typsicheren Zugriff auf seine Felder über die Eigenschaft widget.

Wo wird State gespeichert?

Das State-Objekt wird in StatefulElement gespeichert — einer Zwischenschicht zwischen Widget und RenderObject. StatefulElement erstellt State über createState, behält einen Verweis darauf und übergibt State als Besitzer. Das Element wird nur zerstört, wenn das Widget aus dem Baum entfernt wird — bis dahin lebt State im Speicher.

State-Lebenszyklus

Der State-Lebenszyklus ist deterministisch und besteht aus einer strengen Abfolge von Aufrufen. Das Verständnis dieser Abfolge ist die Grundlage für korrektes Ressourcenmanagement und die Vermeidung von Speicherlecks.

initState — Initialisierung

initState wird zuerst beim Erstellen von State aufgerufen. In dieser Methode werden Controller, Stream-Abonnements, Timer und Anfangswerte von Feldern initialisiert. Der Aufruf von super.initState() in der ersten Zeile ist obligatorisch. In der initState-Phase ist der Widget-Baum noch nicht vollständig montiert, daher können Methoden wie MediaQuery.of(context) möglicherweise nicht korrekt funktionieren.

didChangeDependencies

didChangeDependencies wird nach initState und bei jeder Änderung von InheritedWidget-Abhängigkeiten aufgerufen. Hier, nicht in initState, sollte MediaQuery.of(context) oder Theme.of(context) aufgerufen werden, da der Baum zu diesem Zeitpunkt bereits montiert ist. Diese Methode wird auch aufgerufen, wenn das Widget in einen anderen Kontext verschoben wird, in dem InheritedWidget andere Werte bereitstellt.

build — Aufbau der UI

build ist die Hauptmethode von State, die einen Widget-Baum zurückgibt. Sie wird nach initState, nach didChangeDependencies und nach jedem setState aufgerufen. Die build-Methode sollte keine Nebenwirkungen haben — sie beschreibt nur die Benutzeroberfläche basierend auf den aktuellen Werten der State-Felder.

didUpdateWidget

didUpdateWidget wird aufgerufen, wenn das Elternteil das StatefulWidget mit neuen Parametern neu erstellt. State erhält Zugriff auf das alte Widget über oldWidget und kann es mit dem neuen vergleichen. Wenn sich Parameter geändert haben, kann der Zustand aktualisiert, neue Daten geladen oder eine Animation neu gestartet werden.

dispose — Ressourcenfreigabe

dispose ist die letzte Methode, in der alle Ressourcen freigegeben werden: Controller, Abonnements, Timer. Nach dispose wird State als tot markiert: mounted gibt false zurück, der Aufruf von setState löst eine Ausnahme aus. Der Aufruf von super.dispose() in der letzten Zeile der Methode ist obligatorisch.

MethodeWann aufgerufenObligatorisches super
initStateBeim Erstellen von StateJa, in der ersten Zeile
didChangeDependenciesNach initState und bei Änderung von InheritedWidgetJa
buildNach initState, didChangeDependencies, setStateNein
didUpdateWidgetBei einem neuen Widget vom ElternteilJa
setStateBei Aufruf durch den EntwicklerNein
disposeBei Entfernung aus dem BaumJa, in der letzten Zeile

Wie funktioniert State?

Der Arbeitsmechanismus von State basiert auf drei Schlüsselprinzipien: Assoziation mit Element, Reaktivität durch setState und Elternzugriff über die widget-Eigenschaft. Wenn Flutter den Elementbaum erstellt und auf ein StatefulElement stößt, ruft es createState des zugehörigen Widgets auf. Der erstellte State wird im Element gespeichert und existiert, bis das Element entfernt wird.

Beim Aufruf von setState markiert sich State als schmutzig und plant eine Neuerstellung für den nächsten Frame. Wichtig: setState ruft build nicht sofort auf — es registriert nur die Notwendigkeit einer Neuerstellung. Flutter sammelt alle schmutzigen Elemente im aktuellen Frame und erstellt sie stapelweise neu, was die Leistung optimiert. Nach dem build-Aufruf kehrt State in den sauberen Zustand zurück.

Die widget-Eigenschaft ermöglicht es State, die an den StatefulWidget-Konstruktor übergebenen Parameter zu lesen. Da StatefulWidget unveränderlich ist (wie StatelessWidget), ändern sich seine Felder nicht — wenn sich Parameter ändern, erstellt das Elternteil ein neues Widget, und State empfängt es über didUpdateWidget. Dies stellt sicher, dass State immer mit aktuellen Elterndaten arbeitet.

Dart-Codebeispiele

Ein einfaches State-Beispiel mit einem Feld, das von einem Timer geändert wird. Zeigt initState, setState und dispose:

dart
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 seconds elapsed');
  }
}

Ein Beispiel mit der widget-Eigenschaft zum Zugriff auf Elternparameter und Reaktion auf deren Änderungen über didUpdateWidget:

dart
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('Hello, $_displayName!');
  }
}

Im zweiten Beispiel verfolgt State Änderungen des Eingabeparameters name und formatiert die Anzeige nur bei einer tatsächlichen Änderung neu. Ohne die Überprüfung widget.name != oldWidget.name würde die Methode bei jeder Neuerstellung des Elternteils aufgerufen, selbst wenn sich der Name nicht geändert hat — unnötige Arbeit für das Framework.

State vs StatefulWidget

State und StatefulWidget sind zwei verschiedene Klassen in der Flutter-Architektur mit unterschiedlichen Rollen. StatefulWidget ist ein leichter unveränderlicher Wrapper, der die Widget-Konfiguration beschreibt und State erstellt. State ist ein schweres Objekt, das veränderliche Daten speichert, Abonnements verwaltet und die UI erstellt. Diese Trennung ermöglicht es Flutter, Widgets zu zerstören und zu erstellen, ohne den Zustand zu verlieren.

Alle Felder von StatefulWidget müssen final sein und im Konstruktor gesetzt werden — sie ändern sich nach der Erstellung nicht. State hingegen kann seine Felder jederzeit ändern, aber allen Änderungen muss ein setState-Aufruf vorausgehen, damit Flutter von der Notwendigkeit einer Neuerstellung erfährt. Dies ist der Hauptunterschied: StatefulWidget ist „was zu zeigen“, State ist „wie zu zeigen und welche Daten zu verwenden“.

Laut Flutter-Quellcode-Analyse (Flutter SDK, 2026) enthält StatefulWidget nur ein obligatorisches Feld — createState, während State Zugriff auf BuildContext hat, Streams abonnieren, Animationen und Controller verwalten kann. Es wird empfohlen, StatefulWidget so einfach wie möglich zu halten und die gesamte Logik in State zu verschieben.

Warum kann StatefulWidget nicht State sein?

Die Trennung von Widget und State ist eine architektonische Entscheidung, die die Unveränderlichkeit der Konfiguration gewährleistet. Wenn StatefulWidget selbst den Zustand speichern würde, ginge der Zustand bei jeder Neuerstellung des Elternteils verloren. Durch das Verschieben des Zustands in ein separates Objekt garantiert Flutter, dass Daten Neuerstellungen überleben, während Widgets leicht und vergleichbar bleiben.

Zustandsverwaltung zwischen Widgets

Das State-Objekt ist isoliert — es hat keinen direkten Zugriff auf den State anderer Widgets. Für den Datenaustausch zwischen Widgets werden InheritedWidget oder externe Zustandsverwaltungstools verwendet: Provider, Riverpod, Bloc, Redux. Jeder Ansatz löst das Problem anders: InheritedWidget arbeitet über den Widget-Baum, Provider über einen DI-Container, Bloc über Ereignisströme.

Die Wahl des Tools hängt vom Projektumfang ab. Für eine kleine Anwendung reichen InheritedWidget und lokaler State aus. Für mittlere und große Projekte werden Riverpod oder Bloc empfohlen — sie gewährleisten Testbarkeit, Vorhersagbarkeit und Trennung der Logik von der UI. State wird dann nur für lokale Widget-Daten (Fokus, Scrollen, Animation) verwendet.

Laut der Flutter Community Survey 2025 (Flutter Foundation, Dezember 2025) ist Riverpod die beliebteste Zustandsverwaltungslösung in neuen Projekten (38%), gefolgt von Bloc (31%) und Provider (22%). Alle drei Tools sind mit State kompatibel und erfordern keine Aufgabe des Standardlebenszyklus.

Lokaler vs globaler Zustand

  • Lokaler Zustand — im State eines bestimmten Widgets (Scrollposition, Fokusstatus)
  • Globaler Zustand — in einem externen Speicher (Benutzerdaten, Einstellungen, Cache)
  • Regel: Wenn Daten nur von einem Widget verwendet werden — in State speichern
  • Wenn Daten von 2+ Widgets verwendet werden — zu Riverpod/Bloc/Provider verschieben

Häufige Fehler

Der erste Fehler ist, vor setState in einem asynchronen Callback die Überprüfung von mounted zu vergessen. Wenn ein Widget aus dem Baum entfernt wird (z. B. der Benutzer hat den Bildschirm verlassen), aber ein asynchroner Vorgang (HTTP-Anfrage) noch läuft, ist State nach dessen Abschluss bereits tot. Der Aufruf von setState in einem toten State löst eine Ausnahme aus. Die Überprüfung if (mounted) setState(...) löst das Problem.

Der zweite Fehler ist die Initialisierung von InheritedWidget-Abhängigkeiten in initState statt in didChangeDependencies. In initState ist der Kontext noch nicht montiert, daher wird MediaQuery.of(context) eine Ausnahme auslösen. Alle InheritedWidget-Abhängigkeiten sollten in didChangeDependencies oder in build eingerichtet werden.

Der dritte Fehler ist das Ändern von Feldern ohne Aufruf von setState. Wenn ein Entwickler ein State-Feld ohne setState ändert, erfährt Flutter nichts von der Änderung und die UI wird nicht aktualisiert. Zum Beispiel: _list.add(item) ohne nachfolgendes setState((){}) ändert die Liste, aber der Bildschirm bleibt gleich.

Überprüfung von mounted vor setState

Ein Sicherheitsmuster für asynchrone Operationen in State:

dart
Future<void> _fetchData() async {
  final data = await ApiService.fetch();
  if (mounted) {
    setState(() => _data = data);
  }
}

Die Überprüfung von mounted stellt sicher, dass setState nur auf einem lebenden State aufgerufen wird, und verhindert die Ausnahme „setState called after dispose“.

Häufig gestellte Fragen

Wie unterscheidet sich State von StatefulWidget?

StatefulWidget ist eine unveränderliche Widget-Konfiguration, während State ein veränderliches Objekt ist, das Daten speichert und den Lebenszyklus verwaltet. Das Widget kann neu erstellt werden, State nicht. StatefulWidget erstellt State über createState.

Wie viele State-Objekte werden für ein StatefulWidget erstellt?

Genau eines. Die Methode createState wird einmal aufgerufen, wenn das StatefulWidget zum ersten Mal in den Baum eingefügt wird. Selbst wenn das Elternteil mehrmals neu erstellt wird, bleibt das State-Objekt dasselbe, bis sich der Typ oder der Key des Widgets ändert.

Was ist mounted in State?

mounted ist ein boolesches Flag, das anzeigt, ob State sich im Widget-Baum befindet. Nach dem Aufruf von dispose wird mounted false. Es wird zur Überprüfung vor setState in asynchronen Callbacks verwendet, um Ausnahmen zu vermeiden.

Kann State ohne StatefulWidget verwendet werden?

Nein. State ist immer über Generika an ein bestimmtes StatefulWidget gebunden: State<T extends StatefulWidget>. State direkt ohne Verbindung zu einem Widget zu erstellen, ist architektonisch unmöglich.

Was passiert beim Aufruf von setState in dispose?

Eine Ausnahme wird ausgelöst: „setState called after dispose“. Nach dispose gilt State als tot, und alle Versuche, die UI über setState neu zu erstellen, sind verboten. Die Lösung ist, vor jedem setState mounted zu überprüfen.

Zusammenfassung

  • State — Datenverwaltungsobjekt von StatefulWidget, das veränderliche Felder speichert und die UI-Neuerstellung über setState auslöst
  • Lebenszyklus umfasst die obligatorischen Methoden initState, didChangeDependencies, build, didUpdateWidget und dispose, jede mit eigenem Zweck
  • mounted — ein kritisches Sicherheitsflag, das setState-Aufrufe nach Entfernung des Widgets aus dem Baum verhindert
  • widget — State-Eigenschaft zum Zugriff auf die Parameter des zugehörigen StatefulWidget, aktualisiert über didUpdateWidget
  • Isolierung — State hat keinen Zugriff auf andere State; die Kommunikation zwischen Widgets erfolgt über InheritedWidget oder externe Tools
  • setState — ruft build nicht sofort auf, sondern markiert State nur als schmutzig für die Neuerstellung im nächsten Frame
  • Regel — verwenden Sie State für lokale Widget-Daten; verschieben Sie globalen Zustand in externe Schichten (Riverpod, Bloc)

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch