import { useCallback, useState, Dispatch, SetStateAction } from "react"; import { STORAGE_KEY } from "@/state"; type Initializer = () => S; type Setter = (prev: S) => S; type Action = S | Setter | Initializer; function expand(action: Action, prev?: S) { if (typeof action === "function") { return (action as Setter)(prev!); } else { return action; } } export default function useSessionStorage( key: string, fallbackState: S | (() => S) ): [S, Dispatch>, (partial: Partial) => void] { const [value, setValue] = useState(() => { let val = sessionStorage.getItem(STORAGE_KEY + key); if (val) return JSON.parse(val) as S; return expand(fallbackState); }); const set: Dispatch> = useCallback((val) => { setValue((prev) => { const next = expand(val, prev); sessionStorage.setItem(STORAGE_KEY + key, JSON.stringify(next)); return next; }); }, []); const insert = useCallback( (partial: Partial) => set((value) => ({ ...value, ...partial })), [] ); return [value, set, insert]; }