Blog>
Snippets

Synchronizing a React Component with a Browser's LocalStorage

Demonstrate how to use useSyncExternalStore to keep a component's state in sync with the browser's localStorage.
import { useEffect, useState } from 'react';
import { useSyncExternalStore } from 'react';

function useLocalStorageState(key, defaultValue) {
  // Subscribe to changes to the localStorage key
  const subscribe = (callback) => {
    const listener = (e) => {
      if (e.storageArea === localStorage && e.key === key) {
        callback();
      }
    };
    window.addEventListener('storage', listener);
    return () => window.removeEventListener('storage', listener);
  };

  // Get the current state from localStorage
  const getSnapshot = () => {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : defaultValue;
  };

  // Synchronize state to the localStorage key
  return useSyncExternalStore(subscribe, getSnapshot);
}

// Example component using the useLocalStorageState hook
function MyComponent({ storageKey }) {
  const [value, setValue] = useLocalStorageState(storageKey, 'default value');

  useEffect(() => {
    // Update the localStorage whenever the state changes
    localStorage.setItem(storageKey, JSON.stringify(value));
  }, [value, storageKey]);

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </div>
  );
}
This code defines a custom hook 'useLocalStorageState' that can be used to keep a React component's state in sync with the browser's localStorage. It uses 'useSyncExternalStore' to subscribe to localStorage changes and ensure the component gets updated accordingly. The 'MyComponent' component shows an example usage of the custom hook. It has a text input that updates the state and localStorage when changed.