React Native Async Storage函数get操作触发set操作的问题及解决
React 持久化状态 Hook 实现与问题修复
1. React 本地存储实现方案
import { useState, useEffect, Dispatch, SetStateAction } from 'react'; type Response<T> = [ T, Dispatch<SetStateAction<T>>, ] function usePersistedState<T>(key: string, initialState: T): Response<T> { const [state, setState] = useState(() => { const storageValue = localStorage.getItem(key); if (storageValue) return JSON.parse(storageValue); else return initialState }); useEffect(() => { localStorage.setItem(key, JSON.stringify(state)); }, [state, setState]); return [state, setState]; } export default usePersistedState;
2. React Native Async Storage 初始实现(存在问题)
import { useState, useEffect, Dispatch, SetStateAction } from 'react'; type Response<T> = [ T, Dispatch<SetStateAction<T>>, ] function useAsyncStorage<T>(key: string, initialState: T): Response<T> { const [state, setState] = useState(async () => { const value = await AsyncStorage.getItem(key); if (value){ return value } else { return initialState } }); useEffect(() => { AsyncStorage.setItem(key, JSON.stringify(state)); }, [state, setState]); // @ts-ignore return [state, setState]; } export default useAsyncStorage;
问题说明
上述useAsyncStorage函数存在逻辑问题:执行get操作会意外触发set操作。
示例复现:
const [getData, setData] = useAsyncStorage
("data", blankData); setData("data");
// 数据已保存
getData("data");
// 数据被删除
3. 修复后的解决方案
import { useState, useEffect, Dispatch, SetStateAction } from 'react'; import { useAsyncStorage } from "@react-native-async-storage/async-storage"; type Response<T> = [ T, Dispatch<SetStateAction<T>>, ] function usePersistedState<T>(key: string, defaultValue: T): Response<T> { const { getItem, setItem } = useAsyncStorage(key); const [state, setState] = useState<T>(defaultValue); useEffect(() => { (async () => { const data = await getItem(); setState((data ? JSON.parse(data) : undefined) ?? defaultValue); })(); }, [key]); useEffect(() => { (async () => { await setItem(JSON.stringify(state)); })(); }, [key, state]); return [state, setState] as [T, typeof setState]; } export default usePersistedState;
内容的提问来源于stack exchange,提问作者user17257235
相关产品推荐
相关产品推荐

