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.