| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import { useState, useEffect, useCallback } from 'react';
- /**
- * Custom hook for persisting form state to localStorage
- * @param key - Unique key for localStorage
- * @param initialValue - Initial value for the state
- * @returns [state, setState, clearState] tuple
- */
- export function useLocalStorage<T>(
- key: string,
- initialValue: T
- ): [T, (value: T | ((prevValue: T) => T)) => void, () => void] {
- // Always start with initialValue to prevent hydration mismatch
- // Load from localStorage only after client-side hydration
- const [storedValue, setStoredValue] = useState<T>(initialValue);
- // Load value from localStorage after component mounts (client-side only)
- useEffect(() => {
- try {
- const item = window.localStorage.getItem(key);
- if (item) {
- setStoredValue(JSON.parse(item));
- }
- } catch (error) {
- console.warn(`Error loading localStorage key "${key}":`, error);
- }
- }, [key]);
- // Return a wrapped version of useState's setter function that ...
- // ... persists the new value to localStorage.
- const setValue = useCallback(
- (value: T | ((prevValue: T) => T)) => {
- 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 local storage
- if (typeof window !== 'undefined') {
- window.localStorage.setItem(key, JSON.stringify(valueToStore));
- }
- } catch (error) {
- // A more advanced implementation would handle the error case
- console.error(`Error saving localStorage key "${key}":`, error);
- }
- },
- [key, storedValue]
- );
- // Function to clear the stored value
- const clearValue = useCallback(() => {
- try {
- setStoredValue(initialValue);
- if (typeof window !== 'undefined') {
- window.localStorage.removeItem(key);
- }
- } catch (error) {
- console.error(`Error clearing localStorage key "${key}":`, error);
- }
- }, [key, initialValue]);
- return [storedValue, setValue, clearValue];
- }
- /**
- * Hook for auto-saving form state with debouncing
- * @param key - Unique key for localStorage
- * @param value - Current form value
- * @param delay - Debounce delay in milliseconds (default: 500ms)
- */
- export function useAutoSave<T>(key: string, value: T, delay = 500) {
- useEffect(() => {
- const timeoutId = setTimeout(() => {
- if (typeof window !== 'undefined') {
- try {
- window.localStorage.setItem(key, JSON.stringify(value));
- } catch (error) {
- console.error(`Error auto-saving localStorage key "${key}":`, error);
- }
- }
- }, delay);
- return () => clearTimeout(timeoutId);
- }, [key, value, delay]);
- }
|