useAsyncStorage tùy chỉnh hook với useState hook trong React Native

Aug 16 2020

Như chúng ta đã biết, chúng ta không thể sử dụng LocalStorage trong React Native. Thay vào đó, tôi cố gắng tạo một hook tùy chỉnh useAsyncStorage, hoạt động tương tự như hook custome LocalStorage trong phản ứng để lưu trữ dữ liệu trong bộ nhớ cục bộ của thiết bị di động.

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

Trong App.js, tôi nhập useAsyncStorage.js và thử sử dụng nó để lưu trữ dữ liệu trong bộ nhớ cục bộ của thiết bị di động.

import useAsyncStorage from './useAsyncStorage';

Để viết tắt nó:

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

Để setValue:

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

Nó hoạt động như mong đợi và thiết lập dữ liệu, nhưng nó không thể truy xuất dữ liệu từ AsyncStorage sau khi tải lại ứng dụng.

Bất cứ ai có thể vui lòng giúp đỡ? Tôi có làm sai điều gì đó trong hook tùy chỉnh useAsyncStorage không? Tại sao dữ liệu không được lưu trữ trong AsyncStorage?

Trả lời

1 YajanaNRao Aug 16 2020 at 14:53

Việc useAsyncStoragetriển khai này đang làm việc cho tôi.

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

Liên kết đến Snack demo:

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

Tài liệu tham khảo:

https://usehooks.com/useLocalStorage/

Cách triển khai tương tự khác:

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

1 Earl Dec 04 2020 at 11:32

Bạn có thể thử móc tùy chỉnh này mà tôi đã làm

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

bạn cũng có thể sử dụng FromStorage đã truy xuất để kiểm tra xem dữ liệu đã được truy xuất thành công từ AsyncStorage hay chưa.

Wen Aug 16 2020 at 16:15

Tôi thấy cái này phù hợp với tôi.

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

Tài liệu tham khảo: https://gist.github.com/msukmanowsky/08a3650223dda8b102d2c9fe94ad5c12