Skip to content
D
Documentation

Reset store state

how-to
2 min readUpdated

Reset a store after logout or clearing a session. Use create to keep state and actions together, then reset through getInitialState(). The examples below restore the displayed counts and leave the increment actions available for subsequent updates.

1. Reset one store

Add a reset action that calls set(store.getInitialState()). getInitialState() returns the state created by the initializer, including its actions; it does not capture the most recent update.

In a React browser project with Zustand installed, use this as src/main.tsx and provide an element with id="root" in your HTML:

tsx
import { createRoot } from 'react-dom/client'
import { create } from 'zustand'

type BearState = {
  bears: number
  increase: (by: number) => void
  reset: () => void
}

const useBearStore = create<BearState>()((set, _get, store) => ({
  bears: 0,
  increase: (by) => set((state) => ({ bears: state.bears + by })),
  reset: () => set(store.getInitialState()),
}))

function ResetZoo() {
  const bears = useBearStore((state) => state.bears)
  const increase = useBearStore((state) => state.increase)
  const reset = useBearStore((state) => state.reset)

  return (
    <section>
      <p>{bears} bears</p>
      <button onClick={() => increase(5)}>Increase by 5</button>
      <button onClick={reset}>Reset</button>
    </section>
  )
}

createRoot(document.getElementById('root')!).render(<ResetZoo />)
The bear count starts at zero, with buttons to increase it and reset the store.

The component starts at 0 bears. Click Increase by 5, then Reset: the count returns to zero. Click Increase by 5 again to confirm the action still works. Each selector subscribes to one field of the store.

If you keep a separate initialState object containing only data, reset: () => set(initialState) also works: set merges that object at one level, retaining the actions.

Try the basic reset demo.

2. Reset several stores together

Register a reset callback when you create each store. Use the library's StateCreator type for the initializer rather than describing its signature yourself. This helper handles stores without middleware and returns the bound hook from create.

Replace src/main.tsx with this example. Both stores are connected to the rendered component, so Reset all stores visibly restores both counts.

tsx
import { createRoot } from 'react-dom/client'
import { create, type StateCreator } from 'zustand'

const storeResetFns = new Set<() => void>()

function createResettable<T>(stateCreator: StateCreator<T>) {
  const store = create<T>()(stateCreator)
  storeResetFns.add(() => {
    store.setState(store.getInitialState(), true)
  })
  return store
}

function resetAllStores() {
  storeResetFns.forEach((reset) => reset())
}

type BearState = {
  bears: number
  addBear: () => void
}

type FishState = {
  fish: number
  addFish: () => void
}

const useBearStore = createResettable<BearState>((set) => ({
  bears: 0,
  addBear: () => set((state) => ({ bears: state.bears + 1 })),
}))

const useFishStore = createResettable<FishState>((set) => ({
  fish: 2,
  addFish: () => set((state) => ({ fish: state.fish + 1 })),
}))

function ResetZoo() {
  const bears = useBearStore((state) => state.bears)
  const addBear = useBearStore((state) => state.addBear)
  const fish = useFishStore((state) => state.fish)
  const addFish = useFishStore((state) => state.addFish)

  return (
    <section>
      <p>{bears} bears, {fish} fish</p>
      <button onClick={addBear}>Add bear</button>
      <button onClick={addFish}>Add fish</button>
      <button onClick={resetAllStores}>Reset all stores</button>
    </section>
  )
}

createRoot(document.getElementById('root')!).render(<ResetZoo />)
The display starts at zero bears and two fish, with separate add buttons and one button to reset both stores.

Click both add buttons, then Reset all stores. The display returns to 0 bears, 2 fish. Both add buttons still work because each replacement supplies the complete initial state, including actions. The callbacks reset stores one after another; this is not a cross-store transaction.

Only stores created through createResettable enter this registry. Keep this pattern for application-lifetime stores; for dynamically scoped stores, manage registrations alongside their scope and lifecycle.

Try the advanced reset demo.

Reset options

The second argument to set or setState controls how an object reset applies:

OptionTypeDefaultWhat it does
replacefalse or trueOmitted (undefined)For object state, omission or false merges at one level; true replaces the state with the supplied complete state.

For replacement typing and complete-state requirements, see Type stores and middleware.

Pitfalls

Do not call get synchronously while constructing the initial state. It returns undefined before that state exists, and accessing a field can throw even when TypeScript accepts the code. Read the store only after initialization—for example, inside an action called from a button. Likewise, keep the getInitialState() call inside the reset callback, as shown above.

Was this page helpful?

Reset store state — zustand · GPT-6.1 Sol