← Back to all snippets
JAVASCRIPT

Persist React State with a Custom useLocalStorage Hook

Implement a custom `useLocalStorage` React hook to easily store and retrieve component state from the browser's local storage, ensuring data persistence across sessions.

import React, { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error('Error reading from localStorage:', error);
      return initialValue;
    }
  });

  useEffect(() => {
    try {
      window.localStorage.setItem(key, JSON.stringify(storedValue));
    } catch (error) {
      console.error('Error writing to localStorage:', error);
    }
  }, [key, storedValue]);

  return [storedValue, setStoredValue];
}

function UserSettings() {
  const [theme, setTheme] = useLocalStorage('app-theme', 'light');
  const [username, setUsername] = useLocalStorage('user-name', 'Guest');

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  return (
    <div style={{ padding: '20px', background: theme === 'dark' ? '#333' : '#f0f0f0', color: theme === 'dark' ? '#f0f0f0' : '#333' }}>
      <h1>User Settings</h1>
      <p>Current Theme: {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>

      <p>Username: {username}</p>
      <input
        type="text"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
        style={{ padding: '8px', background: theme === 'dark' ? '#555' : '#fff', color: theme === 'dark' ? '#f0f0f0' : '#333' }}
      />
      <p>Your theme and username will persist even if you close and reopen the browser tab.</p>
    </div>
  );
}

export default UserSettings;
How it works: The `useLocalStorage` custom hook provides a convenient way to persist a component's state in the browser's `localStorage`. It initializes the state by attempting to retrieve a value from `localStorage` using a provided `key`; if no value is found or an error occurs, it falls back to an `initialValue`. An `useEffect` hook then ensures that any changes to this state are automatically written back to `localStorage`, making the data persistent across browser sessions. It returns the current state and a setter function, just like `useState`.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs