useLocalStorage (React)

Save to localStorage whenever state changes and read form it for the first render.

import type { Dispatch, SetStateAction } from 'react'
import { useCallback, useEffect, useState } from 'react'
const useLocalStorage = <T>(
key: string,
initialValue: T
): [get: T, set: Dispatch<SetStateAction<T>>, clear: () => void] => {
const [state, setState] = useState<T>(() => {
const cached = localStorage.getItem(key)
if (!cached) return initialValue
try {
return JSON.parse(cached) as T
} catch (err) {
return initialValue
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state))
}, [state, key])
const clearState = useCallback(() => {
}, [initialValue])
return [state, setState, clearState]


  • We use useCallback for the clearState function to prevent unnecessary re-renders if you use the clearState function inside a useEffect or useCallback and list it in the dependency array.


  • This version of the hook with only work client-side and will throw an error you server-render a component using the hook
  • You should only run the hook once per key at a time - the hook doesn't handle changes when another instance of the hook updates the matching key in localStorage. If you do want to handle that, check out useSyncedLocalStorage


const Example = () => {
const [input, setInput] = useLocalStorage('example:input', '')
return (
<input value={input} onChange={e => setInput(} />


Watch the value for the example:input key in the Application > Local Storage section in your devtools as you type in the input. If you're on mobile, enter some text into the input, and reload the page - when you do, you'll see the same text that you entered pre-filled.

Created 03/26/21Updated 03/18/23
Found a mistake, or want to suggest an improvement? Edit on GitHub here
and see edit history here