← back to Watches
src/hooks/useLocalStorage.js
57 lines
import { useState, useEffect } from 'react';
/**
* Custom hook for localStorage with SSR safety
* Usage: const [value, setValue] = useLocalStorage('key', defaultValue);
*/
export function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
if (typeof window === 'undefined') {
return initialValue;
}
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(`Error loading ${key} from localStorage:`, error);
return initialValue;
}
});
const setValue = (value) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
} catch (error) {
console.error(`Error saving ${key} to localStorage:`, error);
}
};
return [storedValue, setValue];
}
/**
* Custom hook for dark mode with system preference detection
*/
export function useDarkMode() {
const [darkMode, setDarkMode] = useLocalStorage('darkMode', null);
useEffect(() => {
if (darkMode === null && typeof window !== 'undefined') {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setDarkMode(prefersDark);
}
}, [darkMode, setDarkMode]);
useEffect(() => {
if (typeof window !== 'undefined' && darkMode !== null) {
document.documentElement.classList.toggle('dark', darkMode);
}
}, [darkMode]);
return [darkMode, setDarkMode];
}