stores & scopes
A store holds state that outlives a single component. Where state is ephemeral
(resets on unmount), a store persists for the lifetime of its scope.
export store counterStore { state count: number = 0 action inc() { count = count + 1 }}import { StoreRegistry, __registerStoreRestore, createStoreInstance, type StoreSurface } from "@reactra/store"
export const counterStore = { name: "counterStore", kind: "export", factory: () => createStoreInstance((notify) => { let count = (0) as number const inc = () => { count = count + 1 ; notify(); } __registerStoreRestore("counterStore", (next) => { let __written = 0 if ("count" in next) { count = next["count"] as typeof count; __written++ } notify() return __written }) return () => ({ count, inc }) }),}export type counterStore = StoreSurface<typeof counterStore>
if (import.meta.hot) { import.meta.hot.accept((newMod) => { if (!newMod) return StoreRegistry.replace(newMod.counterStore) })}Acquiring a store with inject store
Section titled “Acquiring a store with inject store”inject store is the sole way to acquire a store. It has two forms, and the
parentheses are the signal:
inject store counterStore // bare = subscribe to itinject store cartStore({ userId }) // argumented = own its lifecycle- Bare
inject store Xsubscribes the component to the store (re-renders on the fields it reads — subscription is per-field, not whole-store). - Argumented
inject store X({ ... })makes this component the store’s lifecycle owner and passes itsinput.
The store name is bound by an import type { counterStore } from "..." at the top of
the file.
Scopes
Section titled “Scopes”Stores declare a scope: app (one instance for the whole app), session, or
route-scoped. A session store is the usual way to persist component-like state
across route navigation.
input and preserved state
Section titled “input and preserved state”export store cartStore { input userId: string state items: string[] = []}import { StoreRegistry, __registerStoreRestore, createStoreInstance, type StoreSurface } from "@reactra/store"
export const cartStore = { name: "cartStore", kind: "export", factory: () => createStoreInstance((notify) => { let items = ([]) as string[] __registerStoreRestore("cartStore", (next) => { let __written = 0 if ("items" in next) { items = next["items"] as typeof items; __written++ } notify() return __written }) return () => ({ items }) }),}export type cartStore = StoreSurface<typeof cartStore>
if (import.meta.hot) { import.meta.hot.accept((newMod) => { if (!newMod) return StoreRegistry.replace(newMod.cartStore) })}input X: Tis data passed in by the owner via the argumented form (inject store cartStore({ userId })).preserved state Xis a route-store feature: in a route-scoped store it survives re-instantiation as you navigate away and back. It’s only valid in a route store — a plainapp/sessionstore uses ordinarystate.
Next: services & inject.