| name | tanstack-react-store |
| description | Implement global state management in React apps using TanStack Store (@tanstack/react-store). Use when creating stores, derived state, subscriptions, batched updates, or integrating TanStack Store with React components via the useStore hook. Covers createStore, useStore, shallow comparison, batch, derived stores, atoms, and async atoms. |
TanStack React Store
Framework-agnostic reactive data store with a React adapter. Install @tanstack/react-store.
Core API
createStore
Create a writable store with an initial value, or a readonly derived store with a getter function.
import { createStore } from "@tanstack/react-store";
const countStore = createStore(0);
countStore.setState(() => 1);
console.log(countStore.state);
const appStore = createStore({ dogs: 0, cats: 0 });
const doubled = createStore(() => countStore.state * 2);
Store class
store.state / store.get() — read current value
store.setState((prev) => next) — update with updater fn (not available on derived/readonly stores)
store.subscribe((value) => void) — listen to changes, returns { unsubscribe }
Derived stores — previous value
Access the previous derived value via the prev argument:
const sum = createStore<number>((prev) => count.state + (prev ?? 0));
batch
Batch multiple setState calls; subscribers fire once at the end:
import { batch } from "@tanstack/react-store";
batch(() => {
countStore.setState(() => 1);
countStore.setState(() => 2);
});
React Integration
useStore
Subscribe a React component to a store. Accepts a selector for fine-grained re-renders.
import { createStore, useStore } from "@tanstack/react-store";
const store = createStore({ dogs: 0, cats: 0 });
function Display({ animal }: { animal: "dogs" | "cats" }) {
const count = useStore(store, (state) => state[animal]);
return <div>{`${animal}: ${count}`}</div>;
}
Signature:
function useStore<TAtom extends AnyAtom | undefined, T>(
atom: TAtom,
selector: (snapshot: AtomState) => T,
compare?: (a: T, b: T) => boolean,
): T;
atom — store or atom instance
selector — derive the slice of state needed (keeps re-renders minimal)
compare — optional custom equality check (default: Object.is)
shallow
Use shallow as the compare function when selecting objects/arrays to avoid unnecessary re-renders:
import { useStore, shallow } from "@tanstack/react-store";
const items = useStore(store, (s) => s.items, shallow);
Updating state from event handlers
Call setState outside of React — no hooks needed:
const updateState = (animal: string) => {
store.setState((state) => ({
...state,
[animal]: state[animal] + 1,
}));
};
Best Practices
- Define stores outside components — stores are singletons; instantiate at module level.
- Use selectors — always pass a selector to
useStore to avoid full-state re-renders.
- Use
shallow — when selecting objects/arrays, pass shallow as the compare fn.
- Batch related updates — wrap multiple
setState calls in batch() to notify subscribers once.
- Prefer derived stores over manual sync — use
createStore(() => ...) for computed values instead of manually keeping stores in sync.
- Immutable updates —
setState updater must return a new reference (spread objects/arrays).
- Cleanup subscriptions — call
unsubscribe() returned by store.subscribe() when done.
API Reference
For detailed type signatures and advanced APIs (atoms, async atoms, observers), see references/api-reference.md.