use-session-storage-state
React hook that persist data in sessionStorage
Install
React 18 and above:
npm install use-session-storage-state
⚠️ React 17 and below. For docs, go to the react-17 branch.
npm install use-session-storage-state@17
Why
- Clone of
use-local-storage-state
that I've been actively maintaining for the past 4 years.
- SSR support.
- Works with concurrent rendering and React 19.
- Handles the
Window
storage
event and updates changes across iframe's. Disable with storageSync: false
.
- In-memory fallback when
sessionStorage
throws an error and can't store the data. Provides a isPersistent
API to let you notify the user their data isn't currently being stored.
- Aiming for high-quality with my open-source principles.
Usage
import useSessionStorageState from 'use-session-storage-state'
export default function Todos() {
const [todos, setTodos] = useSessionStorageState('todos', {
defaultValue: ['buy avocado', 'do 50 push-ups']
})
}
Todo list example
import React, { useState } from 'react'
import useSessionStorageState from 'use-session-storage-state'
export default function Todos() {
const [todos, setTodos] = useSessionStorageState('todos', {
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>
))}
</>
)
}
Notify the user when sessionStorage
isn't saving the data using the isPersistent
property
There are a few cases when sessionStorage
isn't available. The isPersistent
property tells you if the data is persisted in sessionStorage
or in-memory. Useful when you want to notify the user that their data won't be persisted.
import React, { useState } from 'react'
import useSessionStorageState from 'use-session-storage-state'
export default function Todos() {
const [todos, setTodos, { isPersistent }] = useSessionStorageState('todos', {
defaultValue: ['buy avocado']
})
return (
<>
{todos.map(todo => (<div>{todo}</div>))}
{!isPersistent && <span>Changes aren't currently persisted.</span>}
</>
)
}
Removing the data from sessionStorage
and resetting to the default
The removeItem()
method will reset the value to its default and will remove the key from the sessionStorage
. It returns to the same state as when the hook was initially created.
import useSessionStorageState from 'use-session-storage-state'
export default function Todos() {
const [todos, setTodos, { removeItem }] = useSessionStorageState('todos', {
defaultValue: ['buy avocado']
})
function onClick() {
removeItem()
}
}
Why does my component re-renders twice?
If you are hydrating your component (for example, if you are using Next.js), your component might re-render twice. This is behavior specific to React and not to this library. It's caused by the useSyncExternalStore()
hook. There is no workaround. This has been discussed in the issues: https://github.com/astoilkov/use-local-storage-state/issues/56.
If you want to know if you are currently rendering the server value you can use this helper function:
function useIsServerRender() {
return useSyncExternalStore(() => {
return () => {}
}, () => false, () => true)
}
API
useSessionStorageState(key: string, options?: SessionStorageOptions)
Returns [value, setValue, { removeItem, isPersistent }]
when called. The first two values are the same as useState()
. The third value contains two extra properties:
removeItem()
— calls sessionStorage.removeItem(key)
and resets the hook to it's default state
isPersistent
— boolean
property that returns false
if sessionStorage
is throwing an error and the data is stored only in-memory
key
Type: string
The key used when calling sessionStorage.setItem(key)
and sessionStorage.getItem(key)
.
⚠️ Be careful with name conflicts as it is possible to access a property which is already in sessionStorage
that was created from another place in the codebase or in an old version of the application.
options.defaultValue
Type: any
Default: undefined
The default value. You can think of it as the same as useState(defaultValue)
.
options.storageSync
Type: boolean
Default: true
Setting to false
doesn't subscribe to the Window storage event. If you set to false
, updates won't be synchronized across iframes.
Note: Unlike localStorage
, sessionStorage
doesn't fire the storage
event across tabs and windows.
options.serializer
Type: { stringify, parse }
Default: JSON
JSON does not serialize Date
, Regex
, or BigInt
data. You can pass in superjson or other JSON
-compatible serialization library for more advanced serialization.
Related