Skip to main content

useLocalStorage

A hook that persists an array of state to localStorage, hydrating from any existing stored value after mount.

The hook​

useLocalStorage.ts
import { useState, useEffect, Dispatch, SetStateAction } from 'react';

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

useEffect(() => {
const storedValue = localStorage.getItem(key);
if (storedValue) {
setValue(JSON.parse(storedValue));
}
}, [key]);

useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);

return [value, setValue];
};
tip

The value starts out as initialState and only loads from localStorage inside a useEffect, on purpose — reading localStorage directly during the initial render breaks server-side rendering (Docusaurus builds a static site) and causes a hydration mismatch.

Try it​

const [items, setItems] = useLocalStorage<string>({
initialState: [],
key: 'my-items',
});

    Stored under the tils-demo-items localStorage key — refresh the page, it's still there.