createStore
Creates a store with an initial state and actions that can modify the state.
const store = createStore(config);Parameters
Section titled “Parameters”config- The configuration for the store.
Returns
Section titled “Returns”The created store with state management methods.
get- Returns the current state of the store.set- Sets the state of the store. If the new state is the current state itself (e.g.set((state) => state)), subscribers andonChangeare not notified.reset- Resets the state of the store to its initial value.initialState- The initial state of the store.actions- Actions that can modify the state of the store (if provided).subscribe- Subscribes to changes in the state of the store. Returns an unsubscribe function.
Configuration
Section titled “Configuration”The config object can contain the following properties:
Setup
initialState- The initial state of the store.actions- A function that defines actions that can modify the state.
Lifecycle hooks
onLoad?- Invoked when the store is created.onAttach?- Invoked when the store is subscribed to.onDetach?- Invoked when the store is unsubscribed from.onChange?- Invoked whenever the state changes.
Each hook receives a context object with:
get- Returns the current state of the store.set- Sets the state of the store.reset- Resets the state of the store to its initial value.initialState- The initial state of the store.
Persistence
persist?- Whether to persist the state of the store.key?- The unique key used to identify this store in storage. Required ifpersistis true.storage?- The storage to use for persisting the state. Defaults to local storage if available. The state is synchronized with the storage when the window gains focus, and when another tab changes local or session storage.syncWithStorageOn?- When to initially synchronize the store’s state with the storage. Defaults to “load”. Set to “attach” when using SSR to avoid hydration errors. See Persisting state with SSR.serializer?- The serializer to use for storing the state. Defaults to JSON.onStorageError?- Invoked with the error when the storage or the serializer throws, or with aStorageUnavailableErrorwhen no storage is available. The failed read or write is skipped and the state is left unchanged. Storage errors are not logged, so use this to surface them. A missing storage provider is also reported during SSR, where it can be safely ignored.
Basic example
Section titled “Basic example”import { createStore } from "dharma-core";
const store = createStore({ initialState: { count: 0 }, actions: ({ set }) => ({ increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })), }),});Lifecycle hooks
Section titled “Lifecycle hooks”import { createStore } from "dharma-core";import { State } from "./types";
const initialState: State = { data: null, loading: true, error: null };const store = createStore({ initialState, onAttach: async ({ set }) => { try { const response = await fetch("https://api.example.com/data"); const data = await response.json(); set({ data, loading: false }); } catch (error) { set({ error, loading: false }); } }, onDetach: ({ reset }) => reset(),});Persisting state
Section titled “Persisting state”import { createStore } from "dharma-core";
const store = createStore({ persist: true, key: "count", initialState: { count: 0 }, actions: ({ set }) => ({ increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })), }),});Persisting state with SSR
Section titled “Persisting state with SSR”By default, a persisted store reads from storage as soon as it is created. When the page is rendered on the server, the server has no access to the client’s storage and renders with the initial state, while the client renders with the persisted state. The two renders differ, which causes a hydration mismatch.
Setting syncWithStorageOn to "attach" delays the read until the store is first subscribed to. With useStore that happens after hydration, so the first client render matches the server, and the persisted state is applied right after as a regular update.
import { createStore } from "dharma-core";
const store = createStore({ persist: true, key: "count", syncWithStorageOn: "attach", initialState: { count: 0 }, onStorageError: (error) => { // There's no storage on the server, so nothing to report if (typeof window === "undefined") return; reportError(error); },});Custom storage and serializer
Section titled “Custom storage and serializer”import { createStore } from "dharma-core";import superjson from "superjson";
const store = createStore({ persist: true, key: "count", storage: sessionStorage, serializer: superjson, initialState: { count: 0 }, actions: ({ set }) => ({ increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })), }),});Handling storage errors
Section titled “Handling storage errors”import { createStore } from "dharma-core";
const store = createStore({ persist: true, key: "count", initialState: { count: 0 }, onStorageError: (error) => reportError(error),});