import * as SecureStore from "expo-secure-store"; import * as React from "react"; import { Platform } from "react-native"; type UseStateHook = [[boolean, T | null], (value: T | null) => void]; function useAsyncState( initialValue: [boolean, T | null] = [true, null] ): UseStateHook { return React.useReducer( ( state: [boolean, T | null], action: T | null = null ): [boolean, T | null] => [false, action], initialValue ) as UseStateHook; } export async function setStorageItemAsync(key: string, value: string | null) { if (Platform.OS === "web") { try { if (value === null) { localStorage.removeItem(key); } else { localStorage.setItem(key, value); } } catch (e) { console.error("Local storage is unavailable:", e); } } else { if (value == null) { await SecureStore.deleteItemAsync(key); } else { await SecureStore.setItemAsync(key, value); } } } export function useStorageState(key: string): UseStateHook { // Public const [state, setState] = useAsyncState(); // Get React.useEffect(() => { if (Platform.OS === "web") { try { if (typeof localStorage !== "undefined") { setState(localStorage.getItem(key)); } } catch (e) { console.error("Local storage is unavailable:", e); } } else { SecureStore.getItemAsync(key).then((value) => { setState(value); }); } }, [key]); // Set const setValue = React.useCallback( (value: string | null) => { setState(value); setStorageItemAsync(key, value); }, [key] ); return [state, setValue]; }