# Create and bind a React store

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`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand#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](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/select-state-efficiently); for nested updates, see [Update nested state](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/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](https://zustand-demo.pmnd.rs/). The repository's [React demo source](https://github.com/pmndrs/zustand/blob/d7a5583cffd80af515f7dfb69583c95cbdc9e2ce/examples/demo/src/App.jsx) creates a store and binds its counter component in the same way.

## Related

- [React quick start](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/react-quick-start)
- [How Zustand works](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/how-zustand-works)
- [React and vanilla stores](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/react-and-vanilla-stores)
- [Select state efficiently](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/select-state-efficiently)
- [Update nested state](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/update-nested-state)
