useStorage
Works just like useState but with real-time integration with local or session storage. the initial state is taken from the chosen storage API and every time you change the state, this new value is automatically updated in the storage API.
Installation
npx rabbithook@latest add use-storage
Usage
import useStorage, { useLocalStorage, useSessionStorage } from "@/hooks/use-storage";
function Component() { const [foo, setFoo] = useLocalStorage("foo", ""); /* This is also valid const [foo, setFoo] = useStorage("foo", "", localStorage); */ const [bar, setBar] = useSessionStorage("bar", "",); /* This is also valid const [bar, setBar] = useStorage("bar", "", sessionStorage); */
return ( <> <p>foo: { foo }</p> <input value={foo} onChange={event => setFoo(event.target.value)} />
<p>bar: { bar }</p> <input value={bar} onChange={event => setBar(event.target.value)} /> </> );}
Code
import { Dispatch, SetStateAction, useState, useEffect, useCallback } from "react";
type IUseStorageReturnType<T> = [T | null, Dispatch<SetStateAction<T | null>>, () => void];type IStorageType = typeof localStorage | typeof sessionStorage;
function useLocalStorage<T>(key: string, defaultValue: T): IUseStorageReturnType<T> { return useStorage(key, defaultValue, window.localStorage);}
function useSessionStorage<T>(key: string, defaultValue: T): IUseStorageReturnType<T> { return useStorage(key, defaultValue, window.sessionStorage);}
function useStorage<T>(key: string, defaultValue: T, storageObject: IStorageType): IUseStorageReturnType<T> { const [value, setValue] = useState<T | null>(() => { const jsonValue = storageObject.getItem(key);
if (jsonValue != null) return JSON.parse(jsonValue);
if (typeof defaultValue === "function") { return defaultValue(); }
return defaultValue; });
useEffect(() => { if (value === undefined) return storageObject.removeItem(key); storageObject.setItem(key, JSON.stringify(value)); }, [key, value, storageObject])
const remove = useCallback(() => { setValue(null); }, [])
return [value, setValue, remove]}
export { useLocalStorage, useSessionStorage };export default useStorage;
import { useCallback, useEffect, useState } from "react";
function useLocalStorage(key, defaultValue) { return useStorage(key, defaultValue, window.localStorage);}
function useSessionStorage(key, defaultValue) { return useStorage(key, defaultValue, window.sessionStorage);}
function useStorage(key, defaultValue, storageObject) { const [value, setValue] = useState(() => { const jsonValue = storageObject.getItem(key);
if (jsonValue != null) return JSON.parse(jsonValue);
if (typeof defaultValue === "function") { return defaultValue(); }
return defaultValue; });
useEffect(() => { if (value === undefined) return storageObject.removeItem(key) storageObject.setItem(key, JSON.stringify(value)); }, [key, value, storageObject]);
const remove = useCallback(() => { setValue(null); }, [])
return [value, setValue, remove];}
export { useLocalStorage, useSessionStorage };export default useStorage;