Skip to content
D
Documentation

Create and bind a React store

how-to
1 min readUpdated

Create a hook-based store, select the state a component needs, and update it through an action.

Use this pattern for shared application state when components can use the store directly; the hook does not need a provider. The store can hold state and functions together, so colocate each update action with the state it changes.

Create the store and render a consumer

Install Zustand in your React project:

bash
npm install zustand
  1. Create a store with create. Its initializer returns the initial state and actions. In this example, increment uses the current count to return the changed field.
  2. Call the store hook inside a React component with a selector for each value it needs. The counter displays the selected count; clicking +1 calls the selected action, updates the count, and causes the component to render the new value.
  3. Mount the component in the browser. The initial display is 0; each click on +1 increases it by one.
tsx
import { create } from 'zustand'
import { createRoot } from 'react-dom/client'

type CounterStore = {
  count: number
  increment: () => void
}

const useCounterStore = create<CounterStore>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}))

function Counter() {
  const count = useCounterStore((state) => state.count)
  const increment = useCounterStore((state) => state.increment)

  return (
    <section>
      <output aria-live="polite">{count}</output>
      <button onClick={increment}>+1</button>
    </section>
  )
}

function App() {
  return <Counter />
}

const container = document.getElementById('root')!
createRoot(container).render(<App />)

The component subscribes to the values returned by its selectors. When increment calls set with a partial object, Zustand merges that object into the current state, keeping the action alongside the updated count.

Options and pitfalls

This pattern passes no configuration options to create; define the initial fields and actions in its store initializer. For separate state values, use separate selectors as above. If you need a computed object or array, see Select state efficiently; for nested updates, see Update nested state.

If you use set with replace: true, it replaces the entire state rather than merging it. Include every state field and action the application still needs in the replacement value, or those fields are removed.

See it running

Try the live Zustand demo. The repository's React demo source creates a store and binds its counter component in the same way.

Was this page helpful?

Create and bind a React store — zustand · GPT-6 Luna