useCreateStorage (localStorage)
TL;DR. The same useCreateStorage, only type: 'localStorage' — data survives
a page reload. The only difference from the memory variant in code is the type field; everything else
(the returned object, the lifecycle options, useStorageSubscribe) is identical.
The same end-to-end todo domain (TodoState, initialTodoState — see MemoryStorage).
Why
Screen state (a draft, the selected filter, local settings) should survive a reload, but setting up a
global module-level store just for that is overkill. useCreateStorage with type: 'localStorage' gives
a component-scoped store, synchronous (ISyncStorage), with automatic persistence to localStorage
and no manual initialize()/destroy().
When to use
A component/screen state should survive a reload (draft, filter, settings), but you don't want to set up a global module-level store.
The data is small and synchronous (
localStoragelimit ~5 MB; everything is serialized to a string).
When not to use
The state is ephemeral (doesn't survive a reload) → memory variant.
Large data or binary, you need async → IndexedDB variant.
You need a global persistent store at the module level → LocalStorage directly or via createSynapse.
The store renders on the server (SSR/SSG) — there's no
localStoragethere; for a module-level store, wrap it inbrowserStorage.
Usage
Copy-paste minimal form:
import { useCreateStorage, useStorageSubscribe } from 'synapse-storage/react'
function TodoApp() {
const { storage, isReady } = useCreateStorage<TodoState>({
type: 'localStorage', // <- the only difference from memory
name: 'todo-hook-local',
initialState: initialTodoState,
})
if (!isReady) return <div>Loading…</div>
// Reading and writing — same as with memory (storage: ISyncStorage<TodoState>)
const todos = useStorageSubscribe(storage, (s) => s.todos)
storage.set('filter', 'completed')
}All parameters (commented)
Differs from memory only in type and the destroyOnUnmount default; here you also
have version/migrate available (the persist is real):
const result = useCreateStorage<TodoState>(
{
type: 'localStorage', // the type selects the hook variant
name: 'todo-hook-local', // the key in localStorage
initialState: initialTodoState, // TState is inferred from it
version: 2, // persist schema version (see Persist migrations). Optional.
migrate: (old, from) => (from < 1 ? { ...old } : old), // upgrade old data to the current schema
// middlewares — the store's middleware configurator (see Middlewares).
},
{
autoInitialize: true, // auto initialize() on mount. Defaults to true.
destroyOnUnmount: true, // destroy() on unmount. Defaults to true for localStorage.
// NB: destroy() of an ephemeral store cleans only the instance; the
// data in localStorage is controlled by the adapter's clearOnDestroy
// (the default for localStorage is not to clear). See LocalStorage.
},
)
// The returned object is identical to the memory variant (storage: ISyncStorage<TodoState> | null etc.).Lifecycle options
| Field | Type | Default | Description |
|---|---|---|---|
| autoInitialize | boolean | true | Automatically call initialize() on mount. |
| destroyOnUnmount | boolean | true | Destroy the storage instance on unmount. |
See also
useCreateStorage (memory) — the base description of the hook and the returned object.
useCreateStorage (indexedDB) — for large/asynchronous data.
LocalStorage — the same storage at the module level (the global variant).
Persist migrations —
version/migrate.browserStorage — an SSR-safe wrapper for a module-level
LocalStorage.