Appearance
useStorageAsync
Reactive Storage with async support.
Demo
Usage
The basic usage refers to useStorage.
tsx
import { useStorageAsync } from '@reause/core'
const [accessToken, setAccessToken] = useStorageAsync('access.token', '', SomeAsyncStorage)
// accessToken may be empty before the async storage is ready
console.log(accessToken) // ""Wait First Loaded
When the user enters your app, useStorageAsync() starts loading the value from an async storage, so you may get the default initial value instead of the real stored value at the very beginning.
tsx
import { useStorageAsync } from '@reause/core'
const [accessToken, setAccessToken] = useStorageAsync('access.token', '', SomeAsyncStorage)
// accessToken may be empty before the async storage is ready
console.log(accessToken) // ""
setTimeout(() => {
// In React this closure captured the first render — the loaded value
// arrives on a re-render and cannot be read from here. Use the `onReady`
// option below to act on the loaded value.
console.log(accessToken) // "" — the first render value, unchanged
}, 500)Upstream lets you wait for the storage to be prepared by await-ing the returned ref. In React the tuple cannot be awaited; instead the onReady callback fires once the first value has been loaded:
tsx
const [accessToken, setAccessToken] = useStorageAsync('access.token', '', SomeAsyncStorage, {
onReady(value) {
// accessToken has loaded — safe to mount the app now
},
})Type Declarations
Toggle
ts
export interface SerializerAsync<T> {
read: (raw: string) => Awaitable<T>;
write: (value: T) => Awaitable<string>;
}
export interface StorageLikeAsync {
getItem: (key: string) => Awaitable<string | null>;
setItem: (key: string, value: string) => Awaitable<void>;
removeItem: (key: string) => Awaitable<void>;
}
export interface UseStorageAsyncOptions<T> extends Omit<UseStorageOptions<T>, 'serializer'> {
serializer?: SerializerAsync<T>;
onReady?: (value: T) => void;
}
export type UseStorageAsyncReturn<T> = [
value: T | null,
setValue: Dispatch<SetStateAction<T | null>>
]
type Awaitable<T> = T | Promise<T>
export interface UseStorageOptions<T> {
window?: Window;
listenToStorageChanges?: boolean;
writeDefaults?: boolean;
mergeDefaults?: boolean | ((storageValue: T, defaults: T) => T);
serializer?: Serializer<T>;
onError?: (error: unknown) => void;
}
export function useStorageAsync(key: string, initialValue: string, storage?: StorageLikeAsync, options?: UseStorageAsyncOptions<string>): UseStorageAsyncReturn<string>
export function useStorageAsync(key: string, initialValue: boolean, storage?: StorageLikeAsync, options?: UseStorageAsyncOptions<boolean>): UseStorageAsyncReturn<boolean>
export function useStorageAsync(key: string, initialValue: number, storage?: StorageLikeAsync, options?: UseStorageAsyncOptions<number>): UseStorageAsyncReturn<number>
export function useStorageAsync<T>(key: string, initialValue: T | (() => T), storage?: StorageLikeAsync, options?: UseStorageAsyncOptions<T>): UseStorageAsyncReturn<T>
export function useStorageAsync<T = unknown>(key: string, initialValue: null, storage?: StorageLikeAsync, options?: UseStorageAsyncOptions<T>): UseStorageAsyncReturn<T>
export function useStorage(key: string, defaults: string, storage?: StorageLike, options?: UseStorageOptions<string>): UseStorageReturn<string>
export function useStorage(key: string, defaults: boolean, storage?: StorageLike, options?: UseStorageOptions<boolean>): UseStorageReturn<boolean>
export function useStorage(key: string, defaults: number, storage?: StorageLike, options?: UseStorageOptions<number>): UseStorageReturn<number>
export function useStorage<T>(key: string, defaults: T | (() => T), storage?: StorageLike, options?: UseStorageOptions<T>): UseStorageReturn<T>
export function useStorage<T = unknown>(key: string, defaults: null, storage?: StorageLike, options?: UseStorageOptions<T>): UseStorageReturn<T>