JAVASCRIPT
Create a useLocalStorage Custom Hook for Persistent State
Build a reusable custom React hook, `useLocalStorage`, to automatically synchronize component state with browser's local storage. Ideal for persisting user preferences.
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
// State to store our value
// Pass initial state function to useState so logic is only executed once
const [storedValue, setStoredValue] = useState(() => {
if (typeof window === 'undefined') {
return initialValue;
}
try {
// Get from local storage by key
const item = window.localStorage.getItem(key);
// Parse stored json or if none return initialValue
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// If error also return initialValue
console.log(error);
return initialValue;
}
});
// useEffect to update local storage when the state changes
useEffect(() => {
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(storedValue));
}
}, [key, storedValue]); // Rerun when key or storedValue changes
return [storedValue, setStoredValue];
}
// Example usage:
function LocalStorageComponent() {
const [name, setName] = useLocalStorage('userName', 'Guest');
const [darkMode, setDarkMode] = useLocalStorage('darkMode', false);
return (
<div>
<h1>Hello, {name}!</h1>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
<button onClick={() => setDarkMode(!darkMode)}>
Toggle Dark Mode: {darkMode ? 'On' : 'Off'}
</button>
<p style={{ background: darkMode ? '#333' : '#fff', color: darkMode ? '#eee' : '#333' }}>
This content respects dark mode preference.
</p>
</div>
);
}
export default LocalStorageComponent;
How it works: This custom hook `useLocalStorage` abstracts away the logic for reading from and writing to `localStorage`. It initializes state by attempting to retrieve a value from `localStorage` associated with a given `key`, falling back to `initialValue` if not found or if an error occurs. A `useEffect` hook ensures that whenever `storedValue` changes, the new value is automatically persisted to `localStorage`. This provides a simple and reusable way to manage state that persists across browser sessions.