Synapsev6.0.0

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 (localStorage limit ~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 localStorage there; for a module-level store, wrap it in browserStorage.

Usage

Copy-paste minimal form:

typescript
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):

typescript
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

FieldTypeDefaultDescription
autoInitializebooleantrueAutomatically call initialize() on mount.
destroyOnUnmountbooleantrueDestroy 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 migrationsversion/migrate.

  • browserStorage — an SSR-safe wrapper for a module-level LocalStorage.