Spaces:
Running
Running
File size: 2,508 Bytes
5012205 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
import { useState, useEffect, useCallback } from 'react';
type SetValue<T> = T | ((val: T) => T);
/**
* Custom hook for persistent localStorage state with SSR support
* @param key The localStorage key
* @param initialValue The initial value if no value exists in localStorage
* @returns A stateful value and a function to update it
*/
export function useLocalStorage<T>(key: string, initialValue: T) {
// State to store our value
// Pass initial state function to useState so logic is only executed once
const [storedValue, setStoredValue] = useState<T>(initialValue);
// Check if we're in the browser environment
const isBrowser = typeof window !== 'undefined';
// Initialize state from localStorage or use initialValue
useEffect(() => {
if (!isBrowser) return;
try {
const item = window.localStorage.getItem(key);
if (item) {
setStoredValue(parseJSON(item));
}
} catch (error) {
console.error(`Error reading localStorage key "${key}":`, error);
}
}, [key, isBrowser]);
// Return a wrapped version of useState's setter function that
// persists the new value to localStorage.
const setValue = useCallback((value: SetValue<T>) => {
if (!isBrowser) return;
try {
// Allow value to be a function so we have same API as useState
const valueToStore =
value instanceof Function ? value(storedValue) : value;
// Save state
setStoredValue(valueToStore);
// Save to localStorage
if (valueToStore === undefined) {
window.localStorage.removeItem(key);
} else {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
} catch (error) {
console.error(`Error setting localStorage key "${key}":`, error);
}
}, [key, storedValue, isBrowser]);
return [storedValue, setValue] as const;
}
// Helper function to parse JSON with error handling
function parseJSON<T>(value: string): T {
try {
return JSON.parse(value);
} catch {
console.error('Error parsing JSON from localStorage');
return {} as T;
}
}
/**
* A hook to get a value from localStorage (read-only) with SSR support
* @param key The localStorage key
* @param defaultValue The default value if the key doesn't exist
* @returns The value from localStorage or the default value
*/
export function useLocalStorageValue<T>(key: string, defaultValue: T): T {
const [value] = useLocalStorage<T>(key, defaultValue);
return value;
} |