SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
1.3 KB · 48 lines typescript
Raw Blame History
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