JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsreact
PrevNext

Learn the concept

Hooks

react
mid
custom-hooks

How would you implement a useLocalStorage custom hook?

custom-hooks
localStorage
persistence
state
hooks
Quick Answer

A useLocalStorage hook syncs React state with the browser's localStorage, providing a useState-like API that automatically persists values across page reloads. It handles JSON serialization, error recovery, SSR safety, and can synchronize across browser tabs via the storage event.

Detailed Explanation

Why useLocalStorage:

  • Provides a drop-in replacement for useState that persists data
  • Abstracts away JSON serialization/deserialization boilerplate
  • Handles edge cases developers often miss (quota errors, SSR, malformed data)
  • Enables cross-tab synchronization for consistent state across windows

Core Implementation Steps:

  1. Accept a key and initial value (same API as useState)
  2. Use lazy initialization to read from localStorage on first render
  3. Parse stored JSON, falling back to initial value on errors
  4. Return a setter that writes to both state and localStorage
  5. Handle JSON.stringify for serialization

Error Handling:

  • JSON.parse can throw on malformed data — wrap in try/catch
  • localStorage.setItem can throw QuotaExceededError — catch and optionally notify
  • localStorage may not exist in SSR environments — check for window
  • Private browsing modes may restrict localStorage — handle gracefully

SSR Safety:

  • Check typeof window !== 'undefined' before accessing localStorage
  • Use lazy initializer in useState to avoid hydration mismatches
  • Consider using useEffect for initial read to match server/client

Cross-Tab Sync:

  • The storage event fires when localStorage changes in another tab
  • Listen to this event to keep all tabs in sync
  • The event does NOT fire in the tab that made the change
  • Parse the new value from the event and update React state

Code Examples

Basic useLocalStorage implementationJavaScript
import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // Lazy initialization: read from localStorage on first render
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = localStorage.getItem(key);
      return item !== null ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.warn(`Error reading localStorage key "${key}":`, error);
      return initialValue;
    }
  });

  // Write to localStorage whenever value changes
  useEffect(() => {
    try {
      localStorage.setItem(key, JSON.stringify(storedValue));
    } catch (error) {
      console.warn(`Error writing localStorage key "${key}":`, error);
    }
  }, [key, storedValue]);

  return [storedValue, setStoredValue];
}

// Usage
function App() {
  const [name, setName] = useLocalStorage('userName', '');

  return (
    <input
      value={name}
      onChange={(e) => setName(e.target.value)}
      placeholder="Enter your name"
    />
  );
}

Real-World Applications

Use Cases

User Preferences Persistence

Storing theme, language, sidebar state, and other UI preferences that should survive page reloads without requiring a backend

Form Draft Auto-Save

Automatically persisting form input as the user types so they don't lose progress if they accidentally close the tab

Shopping Cart State

Keeping cart contents in localStorage so items persist when the user returns later, without requiring authentication

Mini Projects

Local Storage Manager

intermediate

Build a developer tool that displays all localStorage keys, their sizes, lets you edit/delete them, and shows total storage usage with quota warnings

Offline-First Todo App

beginner

Create a todo application that stores all data in localStorage with useLocalStorage, supports cross-tab sync, and shows storage quota usage

Industry Examples

usehooks

Popular React hooks library provides a production-ready useLocalStorage implementation with SSR safety and cross-tab synchronization

Zustand

Offers a persist middleware that uses localStorage to automatically save and rehydrate store state across sessions

Resources

React Docs - Reusing Logic with Custom Hooks

docs

usehooks - useLocalStorage

article

Related Questions

Explain the useState and useEffect hooks and their common patterns.

mid
hooks
Previous
How do useSelector and useDispatch work in React-Redux?
Next
How would you implement a useFetch custom hook?
PrevNext