React hook that persist data in
localStorage
npm install use-local-storage-state
- Actively maintained for the past 2 years — see contributions page.
- SSR support with handling of hydration mismatches.
- Handles the
Window
storage
event and updates changes across browser tabs, windows, and iframe's. - In-memory fallback when
localStorage
throws an error and can't store the data. Provides aisPersistent
API to let you notify the user their data isn't currently being stored. - Aiming for high-quality with my open-source principles.
import useLocalStorageState from 'use-local-storage-state'
export default function Todos() {
const [todos, setTodos] = useLocalStorageState('todos', {
ssr: true,
defaultValue: ['buy avocado', 'do 50 push-ups']
})
}
Todo list example + CodeSandbox link
You can experiment with the example here.
import React, { useState } from 'react'
import useLocalStorageState from 'use-local-storage-state'
export default function Todos() {
const [todos, setTodos] = useLocalStorageState('todos', {
ssr: true,
defaultValue: ['buy avocado']
})
const [query, setQuery] = useState('')
function onClick() {
setQuery('')
setTodos([...todos, query])
}
return (
<>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button onClick={onClick}>Create</button>
{todos.map(todo => (
<div>{todo}</div>
))}
</>
)
}
SSR support
SSR supports includes handling of hydration mismatches. This prevents the following error: Warning: Expected server HTML to contain a matching ...
. This is the only library I'm aware of that handles this case. For more, see discussion here.
import useLocalStorageState from 'use-local-storage-state'
export default function Todos() {
const [todos, setTodos] = useLocalStorageState('todos', {
ssr: true,
defaultValue: ['buy avocado', 'do 50 push-ups']
})
}
Notify the user when localStorage
isn't saving the data using the `isPersistent`
property
There are a few cases when localStorage
isn't available. The isPersistent
property tells you if the data is persisted in localStorage
or in-memory. Useful when you want to notify the user that their data won't be persisted.
import React, { useState } from 'react'
import useLocalStorageState from 'use-local-storage-state'
export default function Todos() {
const [todos, setTodos, { isPersistent }] = useLocalStorageState('todos', {
defaultValue: ['buy avocado']
})
return (
<>
{todos.map(todo => (<div>{todo}</div>))}
{!isPersistent && <span>Changes aren't currently persisted.</span>}
</>
)
}
Removing the data from localStorage
and resetting to the default
The removeItem()
method will reset the value to its default and will remove the key from the localStorage
. It returns to the same state as when the hook was initially created.
import useLocalStorageState from 'use-local-storage-state'
export default function Todos() {
const [todos, setTodos, { removeItem }] = useLocalStorageState('todos', {
defaultValue: ['buy avocado']
})
function onClick() {
removeItem()
}
}
Returns [value, setValue, { removeItem, isPersistent }]
when called. The first two values are the same as useState()
. The third value contains two extra properties:
removeItem()
— callslocalStorage.removeItem(key)
and resets the hook to it's default stateisPersistent
—boolean
property that returnsfalse
iflocalStorage
is throwing an error and the data is stored only in-memory
Type: string
The key used when calling localStorage.setItem(key)
and localStorage.getItem(key)
.
localStorage
that was created from another place in the codebase or in an old version of the application.
Type: any
Default: undefined
The default value. You can think of it as the same as useState(defaultValue)
.
Type: boolean
Default: false
Enables SSR support and handles hydration mismatches. Not enabling this can cause the following error: Warning: Expected server HTML to contain a matching ...
. This is the only library I'm aware of that handles this case. For more, see discussion here.
Type: Pick<typeof JSON, 'stringify' | 'parse'>
Default: JSON
JSON does not serialize Date
, Regex
, or BigInt
data. Can pass in superjson or other JSON
-compatible serialization classes for more advanced serialization.
These are the best alternatives to my repo I have found so far: