hooks-belt
Version:
A comprehensive collection of useful React hooks for common use cases
69 lines • 2.68 kB
JavaScript
import { useState, useEffect, useCallback } from 'react';
/**
* A hook that provides a way to persist state in localStorage.
* Automatically syncs the state with localStorage and handles JSON serialization.
*
* @param key - The localStorage key
* @param initialValue - The initial value if no value exists in localStorage
* @returns A tuple with the current value and a function to update it
*
* @example
* ```tsx
* const [user, setUser] = useLocalStorage('user', { name: 'John', age: 30 })
*
* // Update the user
* setUser({ name: 'Jane', age: 25 })
*
* // The value is automatically saved to localStorage
* ```
*/
export function useLocalStorage(key, initialValue) {
// Get from local storage then parse stored json or return 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.warn(`Error reading localStorage key "${key}":`, error);
return initialValue;
}
});
// Return a wrapped version of useState's setter function that persists the new value to localStorage
const setValue = useCallback((value) => {
try {
// Allow value to be a function so we have the same API as useState
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
// Save to local storage
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
}
catch (error) {
console.warn(`Error setting localStorage key "${key}":`, error);
}
}, [key, storedValue]);
// Listen for changes to this localStorage key in other tabs/windows
useEffect(() => {
const handleStorageChange = (e) => {
if (e.key === key && e.newValue !== null) {
try {
setStoredValue(JSON.parse(e.newValue));
}
catch (error) {
console.warn(`Error parsing localStorage value for key "${key}":`, error);
}
}
};
if (typeof window !== 'undefined') {
window.addEventListener('storage', handleStorageChange);
return () => window.removeEventListener('storage', handleStorageChange);
}
}, [key]);
return [storedValue, setValue];
}
//# sourceMappingURL=useLocalStorage.js.map