Benutzerdefinierter useAsyncStorage-Hook mit useState-Hook in React Native

Aug 16 2020

Wie wir wissen, können wir LocalStorage in React Native nicht verwenden. Ich versuche stattdessen, einen benutzerdefinierten useAsyncStorage-Hook zu erstellen, der dieselbe Funktion wie der LocalStorage-Custome-Hook ausführt, um die Daten im lokalen Speicher des Mobilgeräts zu speichern.

useAsyncStorage.js

import React, { useEffect, useState } from 'react';
import AsyncStorage from '@react-native-community/async-storage';


export default function useAsyncStorage(key, defaultValue) {
  const [storageValue, updateStorageValue] = useState(defaultValue);

  useEffect(() => {
    getStorageValue();
  }, []);

  async function getStorageValue() {
    let value = defaultValue;
    try {
      value = (JSON.parse(await AsyncStorage.getItem(key))) || defaultValue;
    } catch (e) {
      // handle here
    } finally {
      updateStorage(value);
    }
  }

  async function updateStorage(newValue) {
    try {
      await AsyncStorage.setItem(key, JSON.stringify(newValue));
    } catch (e) {
      // handle here
    } finally {
      getStorageValue();
    }
  }

  return [storageValue, updateStorageValue];
}

In App.js importiere ich useAsyncStorage.js und versuche, damit die Daten im lokalen Speicher des Mobilgeräts zu speichern.

import useAsyncStorage from './useAsyncStorage';

Um es zu initialisieren:

const [userLevel, setUserLevel] = useAsyncStorage("userLevel",1)

So setzen Sie den Wert:

 setUserLevel(prevLevel => {
   return prevLevel + 1
 })

Es funktioniert wie erwartet und legt die Daten fest, kann jedoch nach dem erneuten Laden der App keine Daten aus AsyncStorage abrufen.

Könnte jemand bitte helfen? Habe ich beim Verwenden des benutzerdefinierten AsyncStorage-Hooks etwas falsch gemacht? Warum werden Daten nicht in AsyncStorage gespeichert?

Antworten

1 YajanaNRao Aug 16 2020 at 14:53

Diese useAsyncStorageImplementierung funktioniert für mich.

function useAsyncStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState();

  async function getStoredItem(key, initialValue) {
    try {
      const item = await AsyncStorage.getItem(key);
      const value = item ? JSON.parse(item) : initialValue;
      setStoredValue(value);
    } catch (error) {
      console.log(error);
    }
  }

  useEffect(() => {
    getStoredItem(key, initialValue);
  }, [key, initialValue]);

  const setValue = async (value) => {
    try {
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      await AsyncStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.log(error);
    }
  };

  return [storedValue, setValue];
}

Link zur Demo Snack:

https://snack.expo.io/@yajana/useasyncstorage

Referenz:

https://usehooks.com/useLocalStorage/

Andere ähnliche Implementierung:

https://github.com/react-native-hooks/async-storage/blob/master/src/index.js

1 Earl Dec 04 2020 at 11:32

Sie können diesen benutzerdefinierten Haken ausprobieren, den ich gemacht habe

import { useEffect, useState } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage'

const useAsyncStorage = (key, initialValue) => {
  const [data, setData] = useState(initialValue)
  const [retrivedFromStorage, setRetrievedFromStorage] = useState(false)

  useEffect(() => {
    ;(async () => {
      try {
        const value = await AsyncStorage.getItem(key)
        setData(JSON.parse(value) || initialValue)
        setRetrievedFromStorage(true)
      } catch (error) {
        console.error('useAsyncStorage getItem error:', error)
      }
    })()
  }, [key, initialValue])

  const setNewData = async (value) => {
    try {
      await AsyncStorage.setItem(key, JSON.stringify(value))
      setData(value)
    } catch (error) {
      console.error('useAsyncStorage setItem error:', error)
    }
  }

  return [data, setNewData, retrivedFromStorage]
}
export default useAsyncStorage

Sie können auch den retrievedFromStorage verwenden, um zu überprüfen, ob die Daten erfolgreich aus dem AsyncStorage abgerufen wurden.

Wen Aug 16 2020 at 16:15

Ich fand, dass dieser für mich funktioniert.

import { useEffect, useState } from 'react';
import AsyncStorage from '@react-native-community/async-storage';

export default function useAsyncStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(initialValue);
  useEffect(() => {
    AsyncStorage.getItem(key)
      .then(value => {
        if (value === null) return initialValue;
        return JSON.parse(value);
      })
      .then(setStoredValue)
  }, [key, initialValue]);

  const setValue = value => {
    const valueToStore = value instanceof Function ? value(storedValue) : value;
    setStoredValue(valueToStore);
    AsyncStorage.setItem(key, JSON.stringify(valueToStore));
  }

  return [storedValue, setValue];
}

Referenz: https://gist.github.com/msukmanowsky/08a3650223dda8b102d2c9fe94ad5c12