80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
|
|
/**
|
|
* useState but persisted to sessionStorage
|
|
* Useful for preserving UI state (expanded/collapsed sections, etc.)
|
|
*
|
|
* @param key - Storage key (should be unique)
|
|
* @param defaultValue - Default value if nothing in storage
|
|
* @returns [value, setValue] tuple like useState
|
|
*
|
|
* @example
|
|
* const [isExpanded, setIsExpanded] = usePersistedState('sidebar-expanded', false);
|
|
*/
|
|
export function usePersistedState<T>(
|
|
key: string,
|
|
defaultValue: T
|
|
): [T, (value: T | ((prev: T) => T)) => void] {
|
|
const [value, setValue] = useState<T>(() => {
|
|
// Only access sessionStorage on client
|
|
if (typeof window === 'undefined') {
|
|
return defaultValue;
|
|
}
|
|
|
|
try {
|
|
const stored = sessionStorage.getItem(key);
|
|
return stored !== null ? JSON.parse(stored) : defaultValue;
|
|
} catch (error) {
|
|
console.error(`Error reading from sessionStorage (key: ${key}):`, error);
|
|
return defaultValue;
|
|
}
|
|
});
|
|
|
|
// Persist to storage when value changes
|
|
useEffect(() => {
|
|
if (typeof window === 'undefined') return;
|
|
|
|
try {
|
|
sessionStorage.setItem(key, JSON.stringify(value));
|
|
} catch (error) {
|
|
console.error(`Error writing to sessionStorage (key: ${key}):`, error);
|
|
}
|
|
}, [key, value]);
|
|
|
|
return [value, setValue];
|
|
}
|
|
|
|
/**
|
|
* Like usePersistedState but for localStorage (persists between sessions)
|
|
*/
|
|
export function useLocalStorageState<T>(
|
|
key: string,
|
|
defaultValue: T
|
|
): [T, (value: T | ((prev: T) => T)) => void] {
|
|
const [value, setValue] = useState<T>(() => {
|
|
if (typeof window === 'undefined') {
|
|
return defaultValue;
|
|
}
|
|
|
|
try {
|
|
const stored = localStorage.getItem(key);
|
|
return stored !== null ? JSON.parse(stored) : defaultValue;
|
|
} catch (error) {
|
|
console.error(`Error reading from localStorage (key: ${key}):`, error);
|
|
return defaultValue;
|
|
}
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (typeof window === 'undefined') return;
|
|
|
|
try {
|
|
localStorage.setItem(key, JSON.stringify(value));
|
|
} catch (error) {
|
|
console.error(`Error writing to localStorage (key: ${key}):`, error);
|
|
}
|
|
}, [key, value]);
|
|
|
|
return [value, setValue];
|
|
}
|