Zustand in React Native: State Management Guide 2026
Zustand ist die schlanke Alternative zu Redux für React Native. So setzt du typsichere Stores auf, persistierst State mit MMKV und arbeitest mit der New Architecture in 2026.
Zustand ist eine minimalistische State-Management-Bibliothek für React und React Native, die mit nur etwa 1,2 KB gzipped auskommt und ohne Provider, Reducer oder Boilerplate funktioniert. In React Native eignet sich Zustand 2026 hervorragend für globalen State, weil es vollständig kompatibel mit der New Architecture (Fabric, TurboModules), React 19 und Concurrent Rendering ist und auf useSyncExternalStore aufbaut. Dieser Leitfaden zeigt, wie ich Zustand in einem Expo-Projekt einsetze, typsicheren Code schreibe und State mit AsyncStorage oder MMKV persistiere.
Zustand 5.x benötigt React 18.2 oder höher und nutzt intern useSyncExternalStore, vollständig kompatibel mit der React Native New Architecture und React 19.
Im Gegensatz zu Redux Toolkit kommt Zustand ohne <Provider>, Reducer oder Action-Konstanten aus. Ein Store wird mit einer einzigen create()-Funktion definiert.
Selektoren mit flachem Vergleich verhindern unnötige Re-Renders und sind in React-Native-Listen mit FlashList Pflicht, nicht Empfehlung.
Persistenz funktioniert über das offizielle persist-Middleware mit AsyncStorage oder, deutlich schneller, mit MMKV als synchroner Storage-Adapter.
Mit dem devtools-Middleware lässt sich der Store an die Redux DevTools anschließen, auch in React Native mit React Native Debugger.
TypeScript-Inferenz funktioniert in Zustand 5 zuverlässig, wenn Sie das Store-Interface als Generic an create<State>()() übergeben (doppelter Aufruf).
Was ist Zustand und wie funktioniert es?
Zustand (deutsch für „state") ist eine State-Management-Bibliothek, die von Daishi Kato und dem Team rund um Jotai und Valtio gepflegt wird. Sie wurde ursprünglich für React entwickelt, läuft aber unverändert in React Native, weil sie keinerlei DOM-spezifische APIs nutzt. Der Kern besteht aus einer einzigen Funktion namens create(), die einen Hook zurückgibt, mit dem Komponenten den Store lesen und mutieren können.
Technisch basiert Zustand auf einem klassischen Publish-Subscribe-Muster. Jeder Store hält einen aktuellen State, eine Liste von Listenern und drei interne Methoden: getState, setState und subscribe. Beim Aufruf des erzeugten Hooks registriert sich die Komponente intern über useSyncExternalStore aus React 18, was zwei wichtige Konsequenzen hat. Updates sind tearing-frei, und der Store funktioniert ohne Anpassung mit Concurrent Rendering, Suspense und der React Native New Architecture.
Anders als Redux ist Zustand mutationsfreundlich. Sie können entweder neue Objekte zurückgeben oder mit dem immer-Middleware direkt mutieren, beides ist erlaubt. Es gibt keine Action-Konstanten, keine Switch-Statements und keinen combineReducers-Aufruf. Ein vollständiger Counter-Store passt in fünf Zeilen, und derselbe Store funktioniert in Web und Mobile identisch. Genau das hat mich vor zwei Jahren überzeugt, eine bestehende Redux-Codebasis Schritt für Schritt zu migrieren, und ich habe es seither nicht bereut.
Zustand vs. Redux Toolkit: Vergleich für React Native
Die häufigste Frage in meinem Posteingang lautet: „Lohnt sich Zustand, wenn das Team bereits Redux Toolkit kennt?" Die ehrliche Antwort ist „meistens ja", denn Zustand reduziert den Boilerplate-Aufwand pro Slice um etwa 60 Prozent und benötigt keinen Provider im Component-Tree. Die folgende Tabelle vergleicht die beiden Bibliotheken auf den Achsen, die in mobilen Apps wirklich zählen.
Kriterium
Zustand 5
Redux Toolkit 2
Bundle-Größe (gzipped)
~1,2 KB
~13 KB (mit React-Redux)
Boilerplate für einen Slice
5 bis 10 Zeilen
20 bis 40 Zeilen
Provider erforderlich
Nein
Ja (<Provider>)
TypeScript-Inferenz
Sehr gut (mit Curry-Syntax)
Sehr gut (createSlice)
Devtools-Support
Über Middleware
Eingebaut
Async-Logik
In Actions, ohne Thunk-Setup
createAsyncThunk oder RTK Query
Persistenz
persist-Middleware (offiziell)
redux-persist (drittanbieter)
New Architecture-kompatibel
Ja
Ja
Redux Toolkit gewinnt, wenn Sie bereits eine ausgereifte Normalisierungs-Strategie mit createEntityAdapter haben oder wenn RTK Query für das Caching von Server-State eingesetzt wird. Für alles andere (lokale UI-States, Auth-Tokens, Theming, ein Warenkorb) ist Zustand schlanker und schneller einzuführen. Wer Server-State separat hält, etwa mit TanStack Query, kommt mit Zustand für Client-State meist vollständig aus.
Zustand in Expo und React Native installieren
Die Installation ist denkbar einfach. Mit Expo SDK 53 oder neuer reicht ein einziger Befehl:
npx expo install zustand
# oder für ein nacktes React Native-Projekt:
npm install zustand
Für Persistenz benötigen Sie zusätzlich einen Storage-Adapter. Mit AsyncStorage:
Wer maximale Performance möchte (etwa für Apps, die beim App-Start hunderte Einträge laden), sollte stattdessen MMKV verwenden. MMKV arbeitet synchron und blockiert damit den ersten Render nicht:
npx expo install react-native-mmkv
MMKV erfordert die New Architecture (Fabric) oder mindestens Expo SDK 50+. Wenn Ihr Projekt noch auf dem alten Bridge-System läuft, sollten Sie zuerst die Migration zur New Architecture abschließen. Wir haben das im FlashList v2 Leitfaden für die New Architecture detailliert beschrieben.
Ihren ersten Store mit TypeScript erstellen
Ein typsicherer Store besteht aus einem Interface, das State und Actions beschreibt, und dem Aufruf von create mit der sogenannten Curry-Syntax (zwei Klammerpaare). Diese Schreibweise ist nötig, damit TypeScript Generics korrekt auflöst. Eine Eigenheit, die in der offiziellen Dokumentation als „middleware typing" bekannt ist und beim ersten Kontakt verwirrend wirkt.
In einer Komponente verwenden Sie den Store wie jeden anderen Hook. Zwei Aufrufe sind üblich: einer für den State, einer für die Action. So bleibt die Komponente unabhängig vom Aufbau des Stores:
Beachten Sie, dass jede Komponente nur die Felder selektiert, die sie wirklich braucht. Dieses Muster ist der Schlüssel zur Performance und wird im nächsten Abschnitt vertieft.
Selektoren und Re-Render-Optimierung
Zustand führt einen Re-Render aus, wenn der Selektor-Rückgabewert sich per Object.is ändert. Wer den ganzen Store auf einmal selektiert, zwingt jede Komponente zu einem Re-Render bei jeder beliebigen Änderung. Das ist der häufigste Performance-Fehler, den ich in größeren React-Native-Apps sehe, und er versteckt sich gerne in scheinbar harmlosen Custom Hooks.
// SCHLECHT: die Komponente rendert bei jeder State-Aenderung neu
const { count, increment } = useCounterStore()
// GUT: nur bei Aenderung von count
const count = useCounterStore((s) => s.count)
const increment = useCounterStore((s) => s.increment)
Wenn Sie mehrere Werte gleichzeitig benötigen, gibt der Selektor ein neues Objekt zurück, und der flache Vergleich schlägt fehl. Die Lösung in Zustand 5 ist die useShallow-Hilfsfunktion:
Für Auth-Tokens, Theme-Einstellungen oder Onboarding-Flags möchten Sie den State über App-Neustarts hinweg behalten. Das offizielle persist-Middleware übernimmt das mit minimaler Konfiguration. So sieht ein Auth-Store mit AsyncStorage aus:
Das partialize-Feld ist wichtig. Es definiert, welche Felder persistiert werden. So bleibt das User-Objekt im RAM, aber das Token überlebt einen App-Restart. Für sichere Token sollten Sie statt AsyncStorage allerdings expo-secure-store verwenden. Dieselbe API funktioniert, weil der Storage-Adapter nur getItem, setItem und removeItem erwartet.
Wer MMKV vorzieht, gewinnt synchrone Reads. Der State ist beim ersten Render bereits hydratisiert, und es gibt keinen Flicker. Die offizielle react-native-mmkv-Dokumentation zeigt einen kompletten Adapter, der drop-in für AsyncStorage einsetzbar ist.
Asynchrone Actions und API-Aufrufe
Anders als Redux benötigen Sie für Async-Actions keinen Thunk-Middleware. Eine Action ist einfach eine Funktion, die async sein darf und intern set aufruft. Das folgende Beispiel lädt einen User-Datensatz und behandelt Lade- und Fehlerzustände:
Für komplexen Server-State mit Caching, Refetching und Optimistic Updates ist TanStack Query die bessere Wahl. Eine bewährte Architektur in 2026 sieht so aus: TanStack Query für alles, was vom Server kommt; Zustand für alles, was nur im Client lebt (UI-State, Auth-Token, lokale Filter). Diese Trennung verhindert, dass Sie API-Caches manuell synchronisieren müssen. Ehrlich gesagt habe ich diese Lektion auf die harte Tour gelernt, als ich anfangs versucht habe, beides in einem Zustand-Store zu halten.
Zustand mit der React Native New Architecture
Mit React Native 0.79+ und Expo SDK 53+ ist die New Architecture (Fabric, TurboModules, Hermes mit React 19) standardmäßig aktiviert. Zustand ist hier seit Version 4.4 vollständig kompatibel, weil es intern useSyncExternalStore nutzt, denselben Hook, den React 19 für externe Stores empfiehlt. Es gibt drei Punkte, die ich in der Praxis beachte.
Erstens: Concurrent Rendering kann denselben Selektor mehrfach in einem Frame aufrufen. Selektoren müssen daher rein sein, also keine Date-Berechnungen, keine Math.random-Aufrufe, keine Logging-Seiteneffekte. Zweitens: Wer Zustand in einem React-Server-Component-Setup einsetzt (etwa Expo Router mit RSC-Mode), muss den Store strikt clientseitig deklarieren, entweder im selben File mit 'use client' oder in einem dedizierten Stores-Verzeichnis. Drittens: Persistenz mit asynchronen Storage-Adaptern führt zu einem kurzen Zeitraum, in dem der Store noch nicht hydratisiert ist. Nutzen Sie useAuthStore.persist.hasHydrated(), um in einem Splash-Screen darauf zu warten. Genau diesen Bug habe ich in meinem letzten Projekt verschlafen, und der Auth-Flow blitzte für einen halben Frame als „eingeloggt" auf, bevor er korrigiert wurde.
Auch wenn Zustand kein Redux ist, lässt sich der gesamte State-Verlauf über die Redux DevTools einsehen. Das ist in React Native besonders wertvoll, weil die klassische Flipper-Integration ab React Native 0.74 nicht mehr offiziell unterstützt wird. Das devtools-Middleware öffnet eine Verbindung zur Browser-Extension oder zum eigenständigen React Native Debugger:
Der dritte Parameter von set ist optional und beschreibt die Action im DevTools-Log. Für Production-Builds sollten Sie das Middleware via process.env.NODE_ENV deaktivieren, sonst hängt die App im Release-Build an einer nicht erreichbaren WebSocket-Verbindung.
Häufige Fehler und wie Sie sie vermeiden
In Code-Reviews sehe ich immer wieder dieselben drei Stolpersteine. Erstens: Den ganzen Store selektieren. Wie oben gezeigt, führt das zu massiven Re-Render-Kaskaden, insbesondere in Listen. Zweitens: Veraltete Closures in Callbacks. Wenn Sie eine Action außerhalb der Komponente abrufen wollen, nutzen Sie useStore.getState() statt eines im Render geschlossenen Werts. Drittens: Den Store-Hook im Render aufrufen, aber das Ergebnis nie verwenden. TypeScript warnt nicht, aber Sie zahlen den Subscriber-Overhead trotzdem.
Ein vierter, subtiler Fehler betrifft Persistenz. Wenn Sie das Datenschema später ändern (zum Beispiel ein Feld umbenennen), bekommen Bestandsnutzer beim Restart den alten persistierten State zurück, der nicht mehr passt. Setzen Sie deshalb von Anfang an version und einen migrate-Callback auf das persist-Config-Objekt. Die einzelnen Schritte sind in der offiziellen Zustand-Persist-Dokumentation beschrieben.
Häufig gestellte Fragen
Ist Zustand besser als Redux für React Native?
Für die meisten React-Native-Apps in 2026 ja. Zustand benötigt etwa 70 Prozent weniger Code pro Feature und ist deutlich kleiner im Bundle. Redux Toolkit ist nur dann überlegen, wenn Sie RTK Query für Server-State oder createEntityAdapter für normalisierte Datenstrukturen brauchen.
Funktioniert Zustand mit der React Native New Architecture?
Ja, vollständig. Zustand 5 nutzt useSyncExternalStore und ist mit Fabric, TurboModules, React 19 und Concurrent Rendering kompatibel. Es gibt keine Migrationsschritte beim Wechsel auf die New Architecture.
Wie persistiere ich Zustand-State in React Native?
Verwenden Sie das offizielle persist-Middleware in Kombination mit AsyncStorage, expo-secure-store oder react-native-mmkv. MMKV ist die schnellste Option, weil sie synchron arbeitet und den ersten Render nicht blockiert.
Brauche ich einen Provider für Zustand?
Nein. Zustand-Stores sind globale Module und werden ohne <Provider> verwendet. Wenn Sie pro Screen einen isolierten Store brauchen (etwa für Wizard-Flows), können Sie optional die Context-API mit einer Store-Factory kombinieren.
Kann ich Zustand mit TanStack Query kombinieren?
Das ist sogar die empfohlene Architektur. TanStack Query verwaltet Server-State mit Caching und Refetching, während Zustand reinen Client-State wie UI-Flags, Auth-Tokens und lokale Filter hält. So vermeiden Sie doppelte Caches.
TanStack Query 5 in React Native: QueryClient für Expo, focusManager, onlineManager, Offline-Persistenz mit AsyncStorage, optimistische Mutations und ein klarer Vergleich zu Zustand. Mit Code-Beispielen für die New Architecture.