在React Native中使用useState挂钩的useAsyncStorage自定义挂钩

问题描述

我们知道,我们不能在React Native中使用LocalStorage。我尝试创建一个useAsyncStorage定制钩子,该钩子与LocalStorage定制钩子具有相同的功能,以将数据存储在移动设备的本地存储中。

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中,我导入useAsyncStorage.js并尝试使用它将数据存储在移动设备的本地存储中。

import useAsyncStorage from './useAsyncStorage';

要初始化它:

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

要设置值:

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

它可以按预期方式工作并设置数据,但在重新加载应用后无法从AsyncStorage检索数据。

有人可以帮忙吗?我在useAsyncStorage自定义挂钩中做错什么了吗?为什么数据不存储在AsyncStorage中?

解决方法

useAsyncStorage实现对我有用。

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

链接到演示小吃:

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

参考:

https://usehooks.com/useLocalStorage/

其他类似的实现方式:

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

,

您可以尝试我制作的这个自定义钩子

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)
      }
    })()
  },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

您还可以使用检索到的存储来检查是否已成功从AsyncStorage中检索数据。

,

我发现这对我有用。

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

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

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

  return [storedValue,setValue];
}

参考:https://gist.github.com/msukmanowsky/08a3650223dda8b102d2c9fe94ad5c12