Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Zustand · Const

React context store

Use a vanilla Zustand store with React context when a store must be initialized from component props or injected into a subtree. Create it once in a provider, pass it through context, and consume selected slices with useStore.

How it works

Create a vanilla Zustand store when a component-scoped instance is needed, place that store in React context, and consume selected state with useStore. A custom hook can centralize context validation and selection for consumers.

Syntax

const StoreContext = createContext<StoreApi<State> | null>(null)
const [store] = useState(() => createStore(createState))
const value = useStore(store, selector)

Parameters

NameTypeDescription
storeStoreApi<T>A vanilla Zustand store created with createStore and supplied through React context.
selector(state: T) => UA function selecting the value returned to the component from the store state.

Returns

The selected value returned by useStore; the provider renders its children with the store available through context.

Key points

  • This pattern is intended for dependency injection and stores whose initial state comes from component props.
  • Create the store lazily inside the provider so the provider owns a stable store instance.
  • Pass the vanilla store itself as the context value rather than putting selected state into context.
  • Read a selected slice by supplying the context store and a selector to useStore.

Common mistakes

  • Use a vanilla store with React context when initialization depends on component props or dependency injection; do not use the deprecated v3 zustand/context helper.
  • Guard consumers against a missing provider so misuse fails immediately instead of producing an unclear runtime error.

Example: A prop-independent context-backed store

import { createContext, useContext, useState } from 'react'
import { createStore, useStore } from 'zustand'

type CounterState = { count: number; increment: () => void }
const createCounterStore = () => createStore<CounterState>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}))

type CounterStore = ReturnType<typeof createCounterStore>
const CounterContext = createContext<CounterStore | null>(null)

function CounterProvider({ children }: { children: React.ReactNode }) {
  const [store] = useState(createCounterStore)
  return <CounterContext.Provider value={store}>{children}</CounterContext.Provider>
}

function Counter() {
  const store = useContext(CounterContext)
  if (!store) throw new Error('Missing CounterProvider')
  const count = useStore(store, (state) => state.count)
  const increment = useStore(store, (state) => state.increment)
  return <button onClick={increment}>{count}</button>
}

Creates one vanilla store for the provider, passes it through React context, and uses Zustand's useStore hook to select state and actions.

When to use it

Prop-based initialization

A component or subtree needs initial state derived from props.

Dependency injection

Tests or embedded widgets need independently controllable store instances.

Independent component state

Repeated UI units must not share one module-level store.

Interview questions

QHow do you make a Zustand store available through React context?

Use createStore to build a vanilla store, create a React context whose value can hold that store, and provide one store instance from a component. Consumers call useStore with the context value and a selector.

Follow-up: Why not simply use create? A bound hook is convenient for a shared store, but a vanilla store plus context supports component-scoped instances and dependency injection.

QHow should the provider preserve the store instance?

Initialize the store in a lazy useState initializer, then pass the stable instance to the provider. This prevents recreating the store during ordinary provider renders.

Follow-up: How can initialization receive props? Define the store factory to accept those props and call it inside the provider's lazy initializer.

QHow does a component read only part of a context-backed store?

useStore takes the vanilla store and a selector, returning the selected value and subscribing the component to it. A custom hook can read the context, validate it, and delegate to useStore.

Follow-up: How can a consumer use a different equality strategy? Use useStoreWithEqualityFn with the store, selector, and equality function.

  • createStore
  • useStore
  • createContext
  • useContext
  • useState
  • useStoreWithEqualityFn

Source: Initialize state with props. Checked 2026-10-15.