-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstorage.ts
More file actions
41 lines (41 loc) · 1.25 KB
/
storage.ts
File metadata and controls
41 lines (41 loc) · 1.25 KB
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
import AsyncStorage from '@react-native-async-storage/async-storage'
import { cloneDeep, merge } from 'lodash'
import { AtomEffect } from 'recoil'
export const persistAtom =
<T>(
key: string,
options?: {
defaultValue?: T
parse?: typeof JSON.parse
stringify?: typeof JSON.stringify
},
): AtomEffect<T> =>
({ onSet, setSelf, trigger }) => {
const parse = options?.parse ?? JSON.parse
const stringify = options?.stringify ?? JSON.stringify
const defaultValue = cloneDeep(options?.defaultValue)
if (trigger === 'get') {
;(async () => {
try {
const savedValue = await AsyncStorage.getItem(key)
if (savedValue) {
const valueToSet = defaultValue
? merge(defaultValue, parse(savedValue))
: parse(savedValue)
setSelf(valueToSet)
}
} catch (error) {
console.error(`failed to recover ${key} from AsyncStorage`)
console.error(error)
}
setSelf(state => merge(cloneDeep(state), { isRetrieved: true }))
})()
}
onSet((newValue, _, isReset) => {
if (isReset) {
AsyncStorage.removeItem(key)
} else {
AsyncStorage.setItem(key, stringify(newValue))
}
})
}