Recoil
Recoil copied to clipboard
Is there any demo about RecoilSyncLocalStorage?
I can't find the RecoilSyncLocalStorage tga in recoil or recoil-sync
That adapter doesn't exist. Someone should really create a PR for it, people would find it useful.
Here's my implementation if it helps, it supports syncing from other tabs as well:
export const localStorageStoreKey = 'localStorage'
const DEFAULT_VALUE = new DefaultValue()
const RecoilSyncLocalStorage: FC<{ children: ReactNode }> = ({ children }) => {
const read: ReadItem = useCallback(
(itemKey) => {
if (typeof document === 'undefined') return DEFAULT_VALUE // SSR
const item = localStorage.getItem(itemKey)
let parsed: unknown
try {
parsed = item === null ? DEFAULT_VALUE : parseJSON(item)
} catch {
parsed = DEFAULT_VALUE
console.warn({ itemKey, item }, 'parseJSON failed')
}
return parsed
},
[],
)
const write: WriteItems = useCallback(
({ diff }) => {
if (typeof document === 'undefined') return // SSR
for (const [key, value] of diff) {
if (value instanceof DefaultValue) {
localStorage.removeItem(key)
} else {
// reasons for setItem to fail: https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem#exceptions
try {
localStorage.setItem(key, JSON.stringify(value))
} catch (err) {
console.warn({ err, key, value }, 'localStorage.setItem failed')
}
}
}
},
[],
)
const listen: ListenToItems = useCallback(
({ updateItem, updateAllKnownItems }) => {
const onStorage = (event: StorageEvent) => {
// ignore clear() calls
if (event.storageArea === localStorage && event.key !== null) {
let parsed: unknown
try {
parsed = event.newValue === null ? DEFAULT_VALUE : parseJSON(event.newValue)
} catch {
parsed = DEFAULT_VALUE
console.warn({ event }, 'parseJSON failed')
}
updateItem(event.key, parsed)
}
}
window.addEventListener('storage', onStorage)
return () => window.removeEventListener('storage', onStorage)
},
[],
)
return (
<RecoilSync storeKey={localStorageStoreKey} read={read} write={write} listen={listen}>
{children}
</RecoilSync>
)
}
function parseJSON(value: string): unknown {
return value === 'undefined' ? undefined : JSON.parse(value)
}
please update the docs about it 👁️