# Initialize state from props

Create a vanilla store from a provider's props and share that store with the React components beneath it.

Use this pattern when a store needs values supplied by a component, such as a scoped feature or an injected dependency. Each mounted provider keeps its own store, and its descendants read and update that store through context.

## Create a store from provider props

Install Zustand in your React project:

```bash
npm install zustand
```

1. Define the provider's input props and the store state, including its action.
2. Create a store factory with [`createStore`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand#createstore) that combines defaults with the supplied props. The factory returns a vanilla store; the provider keeps that instance in state.
3. Put the store in React context. The consumer reads it from context and calls [`useStore`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand#usestore) to select the count and action.
4. Mount the provider with an initial `bears` value. The page renders that count and an **Add bear** button; clicking the button increments the count shown by the consumer.

```tsx
import { createRoot } from 'react-dom/client'
import { createContext, useContext, useState } from 'react'
import type { PropsWithChildren } from 'react'
import { createStore, useStore } from 'zustand'

type BearProps = {
  bears: number
}

type BearState = BearProps & {
  addBear: () => void
}

function createBearStore(initProps?: Partial<BearProps>) {
  const defaultProps: BearProps = { bears: 0 }

  return createStore<BearState>()((set) => ({
    ...defaultProps,
    ...initProps,
    addBear: () => set((state) => ({ bears: state.bears + 1 })),
  }))
}

type BearStore = ReturnType<typeof createBearStore>

const BearContext = createContext<BearStore | null>(null)

type BearProviderProps = PropsWithChildren<BearProps>

function BearProvider({ children, ...props }: BearProviderProps) {
  const [store] = useState(() => createBearStore(props))

  return <BearContext.Provider value={store}>{children}</BearContext.Provider>
}

function BearCounter() {
  const store = useContext(BearContext)
  if (!store) {
    throw new Error('BearCounter must be rendered inside BearProvider')
  }

  const bears = useStore(store, (state) => state.bears)
  const addBear = useStore(store, (state) => state.addBear)

  return (
    <section>
      <output aria-live="polite">{bears} Bears.</output>
      <button type="button" onClick={addBear}>Add bear</button>
    </section>
  )
}

function App() {
  return (
    <BearProvider bears={2}>
      <BearCounter />
    </BearProvider>
  )
}

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

![The mounted counter shows the initial bear count and the Add bear button.](https://atloriaassets.blob.core.windows.net/assets/a438221c-c1af-407c-b9e6-a56c986db846/5e3d30592d56d4b5837f0a9489ec201d.png)

Add `<div id="root"></div>` to the page and load this file from your React entry point. On mount, the consumer displays **2 Bears.**; each click on **Add bear** increases the displayed count by one. The context keeps the store scoped to the provider, while [`useStore`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand#usestore) subscribes the consumer to its selected values.

## Inputs and behavior

| Input | Type | Default | What it does |
| --- | --- | --- | --- |
| `initProps` | `Partial<BearProps>` | `undefined` | Supplies initial prop values for the store; the factory's default count is `0`, and provided values override it. |
| `bears` | `number` | Required on `BearProvider` | Seeds the scoped store in this example. |
| `useStore` selector | `(state: BearState) => U` | Identity selector if omitted | Returns the selected value so the component can render it or call the selected action. |

The vanilla store is created with `createStore`, which returns the store API rather than a React hook. The provider holds one created instance for its mounted lifetime, and the context makes that instance available to descendants. `useStore` returns the selected current-state value and subscribes the component to changes in that selection.

## Pitfalls

- Do not use a module-level store when each provider needs independent state; create the store in the provider's initializer as shown.
- In Next.js, avoid sharing a global store across simultaneous server requests, and do not read or write a store from React Server Components. See [Set up Zustand in Next.js](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/set-up-zustand-in-nextjs).
- For middleware caveats about vanilla store API utilities, see [Subscribe outside React](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/subscribe-outside-react).

## See it running

Open the [Zustand live demo](https://zustand-demo.pmnd.rs/) to see Zustand running in a browser.

## Related

- [Use a vanilla store in React](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/use-a-vanilla-store-in-react)
- [React and vanilla stores](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/react-and-vanilla-stores)
- [Create and bind a React store](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/create-and-bind-a-react-store)
