Skip to content
D
Documentation

Reset store state

how-to
1 min readUpdated

Use a reset action when a screen needs to return a store to its initial values without removing the actions defined on that store.

Reset a React store

Define the reset action beside the state. create gives you a React hook with the store API attached, so the component can select the values and the reset action from the mounted store.

tsx
import { create } from 'zustand'

type FormState = {
  name: string
  email: string
}

type FormActions = {
  setName: (name: string) => void
  setEmail: (email: string) => void
  reset: () => void
}

type FormStore = FormState & FormActions

const useFormStore = create<FormStore>()((set, _get, store) => ({
  name: '',
  email: '',
  setName: (name) => set({ name }),
  setEmail: (email) => set({ email }),
  reset: () => set(store.getInitialState()),
}))

export default function App() {
  const name = useFormStore((state) => state.name)
  const email = useFormStore((state) => state.email)
  const setName = useFormStore((state) => state.setName)
  const setEmail = useFormStore((state) => state.setEmail)
  const reset = useFormStore((state) => state.reset)

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault()
      }}
    >
      <label>
        Name
        <input value={name} onChange={(event) => setName(event.target.value)} />
      </label>
      <label>
        Email
        <input value={email} onChange={(event) => setEmail(event.target.value)} />
      </label>
      <button type="button" onClick={reset}>
        Reset
      </button>
    </form>
  )
}

The reset action calls set(store.getInitialState()); the default shallow merge also retains setName, setEmail, and reset. getInitialState() returns the state captured when the store was created.

Reset a vanilla store used by React

Use createStore when the store must exist independently of React. For its standalone API and React binding, see Vanilla and scoped stores. For this reset pattern, keep the reset action in the state creator and bind the store to React with useStore.

tsx
import { createStore } from 'zustand/vanilla'
import { useStore } from 'zustand'

type FormStore = {
  name: string
  email: string
  setName: (name: string) => void
  setEmail: (email: string) => void
  reset: () => void
}

export const formStore = createStore<FormStore>()((set, _get, store) => ({
  name: '',
  email: '',
  setName: (name) => set({ name }),
  setEmail: (email) => set({ email }),
  reset: () => set(store.getInitialState()),
}))

export default function App() {
  const name = useStore(formStore, (state) => state.name)
  const email = useStore(formStore, (state) => state.email)
  const setName = useStore(formStore, (state) => state.setName)
  const setEmail = useStore(formStore, (state) => state.setEmail)
  const reset = useStore(formStore, (state) => state.reset)

  return (
    <form>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <input value={email} onChange={(event) => setEmail(event.target.value)} />
      <button type="button" onClick={reset}>Reset</button>
    </form>
  )
}

Use useStore to bind the standalone formStore to React, and use its API methods from non-React code.

Reset several stores

Keep one reset function per store in a set, then invoke them from a single resetAllStores action. For a complete replacement, pass true as the second argument to setState, as in the authors' pattern. The StateCreator type describes the function passed to the store creator:

ts
import type { StateCreator } from 'zustand'
import { create as actualCreate } from 'zustand'

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

export const resetAllStores = () => {
  storeResetFns.forEach((reset) => reset())
}

export const create = (<T>() => {
  return (stateCreator: StateCreator<T>) => {
    const store = actualCreate(stateCreator)
    storeResetFns.add(() => {
      store.setState(store.getInitialState(), true)
    })
    return store
  }
}) as typeof actualCreate

The wrapper registers each created store, and resetAllStores() calls every registered reset function. The true replace flag replaces the complete state rather than shallow-merging it.

Pitfalls

  • Do not call setState(initialState, true) for a partial state model: replacement discards properties not present in that value. Use the default merge for the colocated reset action, or include the complete initial state when replacing.
  • If a store is global in a server-rendered application, use a per-request store instead; see Handle server-rendered stores.

Live demo

Try the basic reset-state demo to see the React pattern mounted in a browser. The advanced demo shows the multi-store pattern.

Was this page helpful?