Skip to Content
HooksuseSessionStorage

useSessionStorage

useSessionStorage persists React state in sessionStorage with safe JSON serialization, functional updates, and explicit reset and remove helpers. Values last for the browser tab session and clear when the tab closes.

Live Example

Session draft editor

This demo shows the common pattern: state stays in sync with sessionStorage for the lifetime of the tab.

Session draft

sessionStorage-backed state

Saved for this tab

While this tab stays open, navigation and refreshes keep this text. The hook updates React state and `sessionStorage` together, with reset and remove helpers for the stored key.

Storage support: Unavailable.

Import

import { useSessionStorage } from "react-rsc-kit/client";

Signature

const { value, setValue, remove, reset, isSupported } = useSessionStorage<T>(key, initialValue);

Parameters

NameTypeDescription
keystringsessionStorage key used to read, write, remove, and reset the stored value.
initialValueT | () => TFallback value used when storage is empty, invalid, or unavailable. Supports lazy initialization.

Returns

KeyTypeDescription
valueTCurrent React state value.
setValueDispatch<SetStateAction<T>>Updates state and writes the next value to sessionStorage. Supports functional updates.
remove() => voidRemoves the storage key and resets state back to the fallback value.
reset() => voidRestores the fallback value and writes it back to sessionStorage.
isSupportedbooleanWhether sessionStorage is available in the current environment.

Usage

"use client"; import { useSessionStorage } from "react-rsc-kit/client"; export function DraftMessage() { const { value: draft, setValue, remove } = useSessionStorage("draft-message", ""); return ( <div> <textarea value={draft} onChange={(event) => setValue(event.target.value)} /> <button type="button" onClick={remove}> Clear draft </button> </div> ); }
"use client"; import { useSessionStorage } from "react-rsc-kit/client"; interface UserPreferences { compactMode: boolean; itemsPerPage: number; tags: string[]; } export function PreferencesPanel() { const { value: preferences, setValue, reset, } = useSessionStorage<UserPreferences>("user-preferences", { compactMode: false, itemsPerPage: 20, tags: ["react", "typescript"], }); return ( <div> <p>{preferences.itemsPerPage} items</p> <button type="button" onClick={() => setValue((currentValue) => ({ ...currentValue, compactMode: !currentValue.compactMode, })) } > Toggle compact mode </button> <button type="button" onClick={reset}> Reset preferences </button> </div> ); }

Notes

  • The hook reads existing stored JSON first and falls back to initialValue when the key is missing, malformed, or unavailable.
  • remove() and reset() always resolve the fallback from the latest initialValue you pass for the same key (handy when defaults come from props). Changing initialValue does not overwrite an existing stored value until you call setValue, reset, or remove.
  • setValue avoids writing to storage when the resolved value is unchanged (Object.is), which reduces work for no-op functional updates.
  • remove() clears the key from sessionStorage, while reset() writes the fallback value back into storage.
  • Explicit undefined values are preserved by the hook’s serializer, but values still need to be JSON-serializable to persist correctly.
  • In non-browser environments, the hook falls back to React state and reports isSupported as false.
  • Unlike localStorage, sessionStorage is scoped to the current tab and does not persist after the tab is closed.
Last updated on