React Native Academy · Lektion

Beständiggöra Zustand-tillstånd med AsyncStorage

Omslut en Zustand Store med persist-middleware som använder AsyncStorage så att tillståndet finns kvar efter omstarter av appen och hantera tidpunkten för återhydrering.

Lektion 3 av 413 steg

Beständiggöra Zustand-tillstånd med AsyncStorage är en gratis lektion i React Native Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för React Native Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i React Native Academy innehåller totalt 4 lektioner.

Varför spara tillstånd?

Som standard finns Zustand-tillstånd endast i minnet och går förlorat när appen stängs. Att spara tillstånd innebär att lagra det på enhetens lokala lagring så att det finns kvar när appen startas om. Detta är viktigt för användarinställningar, autentiseringstoken, kundvagnar och andra data som användaren förväntar sig ska finnas kvar när appen öppnas igen.

Installera AsyncStorage

AsyncStorage är standard-API:et för nyckel-värde-lagring i React Native. I Expo:s hanterade arbetsflöde installerar ni community-paketet @react-native-async-storage/async-storage. Zustand:s inbyggda persist-middleware fungerar med alla lagringsadaptrar, och AsyncStorage är det vanligaste valet för mobilappar.

npx expo install @react-native-async-storage/async-storage

Lägga till persist-middleware

Omslut store-skaparen med persist, som importeras från zustand/middleware. Skicka med er store-fabrik och ett konfigurationsobjekt med nyckeln name (AsyncStorage-nyckeln där tillståndet sparas) och nyckeln storage (som pekar på er AsyncStorage-adapter). Zustand hanterar läsning och skrivning automatiskt.

import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const useSettingsStore = create(
  persist<SettingsStore>(
    (set) => ({
      theme: 'light',
      notifications: true,
      setTheme: (theme) => set({ theme }),
      toggleNotifications: () =>
        set((state) => ({ notifications: !state.notifications })),
    }),
    {
      name: 'settings-store',
      storage: createJSONStorage(() => AsyncStorage),
    }
  )
);

Så fungerar persist internt

När store:n skapas för första gången läser persist från AsyncStorage och återfuktar (återställer) tidigare sparat tillstånd innan den första komponenten renderas. När tillståndet ändras via set serialiserar persist automatiskt tillståndet till JSON och skriver det asynkront till AsyncStorage. Allt detta sker utan extra kod i era komponenter.

Hantera fördröjningen vid återfuktning

Avläsningar från AsyncStorage är asynkrona, så vid den första renderingen kan store:n fortfarande innehålla det ursprungliga tillståndet innan återfuktningen är klar. Zustand:s persist-middleware lägger till flaggan _hasHydrated och callback-funktionen onFinishHydration. Använd dessa för att visa en laddningsskärm medan det sparade tillståndet läses in från disken.

const hasHydrated = useSettingsStore((state) => state._hasHydrated);

if (!hasHydrated) {
  return <ActivityIndicator />; // Show loading until store is ready
}

// Alternatively, listen to hydration completion:
useEffect(() => {
  const unsub = useSettingsStore.persist.onFinishHydration(() => {
    setReady(true);
  });
  return unsub;
}, []);

Spara endast en del av tillståndet

Ofta vill ni inte spara allt i store:n — till exempel bör tillfälliga laddningstillstånd eller felmeddelanden inte sparas. Använd alternativet partialize för att välja vilka fält som ska sparas. Det returnerade objektet innehåller endast de nycklar som ni vill skriva till AsyncStorage.

persist<AuthStore>(
  (set) => ({
    user: null,
    token: null,
    isLoading: false,    // transient — don't persist
    error: null,         // transient — don't persist
    login: (user, token) => set({ user, token }),
    logout: () => set({ user: null, token: null }),
  }),
  {
    name: 'auth-store',
    storage: createJSONStorage(() => AsyncStorage),
    partialize: (state) => ({ user: state.user, token: state.token }),
  }
)

Versionshantering och migrering

När ni ändrar strukturen på det sparade tillståndet i en ny appversion kanske gamla data på användarnas enheter inte stämmer överens med den nya formen. Använd alternativen version och migrate för att uppgradera sparat tillstånd från en version till nästa. Öka version vid varje strukturell ändring och hantera det gamla tillståndet i funktionen migrate.

persist<SettingsStore>(
  (set) => ({ /* ... */ }),
  {
    name: 'settings-store',
    storage: createJSONStorage(() => AsyncStorage),
    version: 2,
    migrate: (persistedState: any, version: number) => {
      if (version === 1) {
        // Rename darkMode to theme in version 2
        persistedState.theme = persistedState.darkMode ? 'dark' : 'light';
        delete persistedState.darkMode;
      }
      return persistedState;
    },
  }
)

Rensa sparat tillstånd

För att rensa det sparade tillståndet — till exempel när användaren loggar ut — anropar ni useStore.persist.clearStorage(). Detta tar bort data från AsyncStorage. Ni kan också anropa useStore.getState().reset() för att samtidigt rensa tillståndet i minnet. Genom att göra båda börjar användaren om från början vid nästa appstart.

async function handleLogout() {
  // Clear in-memory state
  useAuthStore.getState().logout();

  // Clear persisted state from AsyncStorage
  await useAuthStore.persist.clearStorage();

  navigation.reset({ index: 0, routes: [{ name: 'Login' }] });
}

Använda SecureStore för känsliga data

För känsliga värden som autentiseringstoken bör ni föredra Expo SecureStore framför vanlig AsyncStorage. SecureStore använder enhetens säkra lagringsmodul (iOS Keychain / Android Keystore) för att kryptera data i vila. Ni kan skapa en anpassad Zustand-lagringsadapter med SecureStore:s metoder getItemAsync och setItemAsync.

import * as SecureStore from 'expo-secure-store';

const secureStorage = {
  getItem: async (name: string) => await SecureStore.getItemAsync(name),
  setItem: async (name: string, value: string) =>
    await SecureStore.setItemAsync(name, value),
  removeItem: async (name: string) =>
    await SecureStore.deleteItemAsync(name),
};

// Use secureStorage instead of AsyncStorage:
storage: createJSONStorage(() => secureStorage),

Felsöka sparat tillstånd

För att kontrollera vad som finns lagrat i AsyncStorage under utvecklingen kan ni anropa AsyncStorage.getAllKeys() och AsyncStorage.multiGet(keys) i utvecklingskonsolen eller på en felsökningsskärm. Ni kan också manuellt rensa gammalt sparat tillstånd med AsyncStorage.clear() när ni testar migreringslogik. Testa alltid med en nyinstallation för att simulera verkliga uppgraderingsscenarier för användare.

// Debug helper — call from a dev-only screen
async function printStorage() {
  const keys = await AsyncStorage.getAllKeys();
  const pairs = await AsyncStorage.multiGet(keys);
  pairs.forEach(([key, value]) => {
    console.log(key, ':', JSON.parse(value ?? 'null'));
  });
}

Exempel på en sparad kundvagns-store

Här är en realistisk kundvagns-store som sparar sin lista över artiklar mellan appstarter. Laddnings- och feltillstånd undantas från sparandet med hjälp av partialize. total beräknas direkt i komponenten i stället för att sparas, så att värdet alltid stämmer överens med items-arrayen efter återfuktning.

export const useCartStore = create(
  persist<CartStore>(
    (set, get) => ({
      items: [],
      addItem: (item) => set((state) => ({ items: [...state.items, item] })),
      removeItem: (id) =>
        set((state) => ({ items: state.items.filter((i) => i.id !== id) })),
      clearCart: () => set({ items: [] }),
    }),
    {
      name: 'cart-store',
      storage: createJSONStorage(() => AsyncStorage),
      partialize: (state) => ({ items: state.items }),
    }
  )
);

Snabbkontroll

Testa er förståelse av koncepten inom React Native Mobile Development från den här lektionen.

Lektionssammanfattning

I den här lektionen har ni lärt er att persist-middleware omsluter en Zustand-store för att automatiskt spara och återställa tillstånd från AsyncStorage, att partialize styr vilka fält som sparas för att undvika att tillfälliga laddnings- eller feltillstånd lagras, och att version tillsammans med migrate hanterar brytande ändringar av tillståndets form mellan appuppdateringar. Nästa steg är att utforska slices-mönstret och Devtools-integrering i Zustand.

Gratis att börja

Lär dig JavaScript med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”Beständiggöra Zustand-tillstånd med AsyncStorage” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen React Native Academy, inklusive ”Beständiggöra Zustand-tillstånd med AsyncStorage”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i React Native Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Beständiggöra Zustand-tillstånd med AsyncStorage”?

Omslut en Zustand Store med persist-middleware som använder AsyncStorage så att tillståndet finns kvar efter omstarter av appen och hantera tidpunkten för återhydrering. Ni övar på React Native Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig React Native Academy?

Du behöver inga förkunskaper. Utbildningen i React Native Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Beständiggöra Zustand-tillstånd med AsyncStorage”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här React Native Academy-lektionen?

Ja. Varje React Native Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Skapa en Zustand Store
  2. Läsa och uppdatera Store-tillstånd i komponenter
  3. Beständiggöra Zustand-tillstånd med AsyncStorage
  4. Slices-mönstret och integrering med Devtools
← Tillbaka till React Native Academy