React Native'de useState kancalı useAsyncStorage özel kanca

Aug 16 2020

Bildiğimiz gibi, LocalStorage'ı React Native'de kullanamayız. Bunun yerine, verileri mobil aygıtın yerel depolamasında depolamak için LocalStorage custome hook ile aynı işlevi gören bir useAsyncStorage özel kancası oluşturmaya çalışıyorum.

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];
}

App.js'de useAsyncStorage.js dosyasını içe aktarıyorum ve verileri mobil cihazın yerel depolamasında depolamak için kullanmayı deniyorum.

import useAsyncStorage from './useAsyncStorage';

Başlamak için:

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

Değer ayarlamak için:

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

Beklendiği gibi çalışır ve verileri ayarlar, ancak uygulama yeniden yüklendikten sonra AsyncStorage'dan veri alamaz.

Biri lütfen yardım edebilir mi? UseAsyncStorage özel kancasında yanlış bir şey mi yaptım? Veriler neden AsyncStorage'da saklanmıyor?

Yanıtlar

1 YajanaNRao Aug 16 2020 at 14:53

Bu useAsyncStorageuygulama benim için çalışıyor.

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];
}

Demo Snack bağlantısı:

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

Referans:

https://usehooks.com/useLocalStorage/

Diğer benzer uygulamalar:

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

1 Earl Dec 04 2020 at 11:32

Yaptığım bu özel kancayı deneyebilirsin

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

Ayrıca, verilerin AsyncStorage'dan başarıyla alınıp alınmadığını kontrol etmek için retrievedFromStorage'ı da kullanabilirsiniz.

Wen Aug 16 2020 at 16:15

Bunun benim için çalıştığını buldum.

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];
}

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