1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
import * as React from "react";
import * as SecureStore from "expo-secure-store";
type UseStateHook<T> = [[boolean, T | null], (value: T | null) => void];
function useAsyncState<T>(
initialValue: [boolean, T | null] = [true, null],
): UseStateHook<T> {
return React.useReducer(
(
_state: [boolean, T | null],
action: T | null = null,
): [boolean, T | null] => [false, action],
initialValue,
) as UseStateHook<T>;
}
export async function setStorageItemAsync(key: string, value: string | null) {
if (value == null) {
await SecureStore.deleteItemAsync(key);
} else {
await SecureStore.setItemAsync(key, value);
}
}
export function useStorageState<T>(key: string): UseStateHook<T> {
// Public
const [state, setState] = useAsyncState<T>();
// Get
React.useEffect(() => {
SecureStore.getItemAsync(key).then((value) => {
if (!value) {
setState(null);
return null;
}
setState(JSON.parse(value) as T);
});
}, [key]);
// Set
const setValue = React.useCallback(
(value: T | null) => {
setState(value);
setStorageItemAsync(key, JSON.stringify(value));
},
[key],
);
return [state, setValue];
}
|