SPB Git
1.3 KB · 48 lines typescript
1'use client';23import { useCallback, useSyncExternalStore } from 'react';45/**6 * Hydration-safe browser storage as an external store: the server snapshot is the fallback, the client reads7 * storage on subscribe (no setState-in-effect), same-tab writes are broadcast through a tiny emitter.8 */9const listeners = new Set<() => void>();10const emit = () => {11  for (const l of listeners) l();12};1314function subscribe(l: () => void) {15  listeners.add(l);16  window.addEventListener('storage', l);17  return () => {18    listeners.delete(l);19    window.removeEventListener('storage', l);20  };21}2223export function useStoredValue(key: string, fallback: string, area: 'local' | 'session' = 'local'): [string, (v: string) => void] {24  const read = useCallback(() => {25    try {26      const store = area === 'local' ? window.localStorage : window.sessionStorage;27      return store.getItem(key) ?? fallback;28    } catch {29      return fallback;30    }31  }, [key, fallback, area]);32  const value = useSyncExternalStore(subscribe, read, () => fallback);33  const set = useCallback(34    (v: string) => {35      try {36        const store = area === 'local' ? window.localStorage : window.sessionStorage;37        if (v) store.setItem(key, v);38        else store.removeItem(key);39      } catch {40        /* private mode */41      }42      emit();43    },44    [key, area],45  );46  return [value, set];47}48
Files · 816281851c37def11cd68afb6b0700b3b590a2cb
Menu

Theme