State

useLocalStorage

State persisted to localStorage (MDN, opens in a new tab).

Demo

Stored under hookli-docs-note — it survives a reload.

Usage

use-local-storage.tsxtsx
import { useLocalStorage } from "hookli";

export function Demo() {
  const { value, setStoredValue } = useLocalStorage("note", "");

  return (
    <div>
      <input value={value} onChange={(e) => setStoredValue(e.target.value)} />
      <button type="button" onClick={() => setStoredValue("")}>Clear</button>
    </div>
  );
}

API

useLocalStorage.d.tsts
useLocalStorage<T>(key: string, initialValue: T): { value: T; setStoredValue: (value: T | ((val: T) => T)) => void }

Parameters

NameTypeDefaultDescription
keystringThe localStorage key to read and write.
initialValueTValue used before hydration and when the key is empty. Prefer a stable reference — the sync effect depends on it.

Returns

NameTypeDescription
valueTThe stored value. Server-rendered as initialValue, then synced from localStorage after mount.
setStoredValue(value: T | ((val: T) => T)) => voidPersists to localStorage and updates state; accepts a value or an updater function.

Hook

The implementation, straight from hookli. Copy it, or install the package.

src/hooks/useLocalStorage.hook.tstsx
import { useEffect, useState } from "react";

export const useLocalStorage = <T>(key: string, initialValue: T) => {
  const [value, setValue] = useState<T>(initialValue);

  useEffect(() => {
    const item = window.localStorage.getItem(key);
    const parsedValue = item ? JSON.parse(item) : initialValue;
    setValue(parsedValue);
  }, [key, initialValue]);

  const setStoredValue = (newValue: T | ((val: T) => T)) => {
    const updatedValue =
      newValue instanceof Function ? newValue(value) : newValue;
    window.localStorage.setItem(key, JSON.stringify(updatedValue));
    setValue(updatedValue);
  };

  return { value, setStoredValue };
};

View source on GitHub

Related hooks