Reuse reducer-based state transitions
An application already models state transitions as pure reducers and typed actions.
Zustand · Function
Zustand's redux middleware builds a store from a reducer and initial state. It adds typed action dispatching while retaining Zustand's store APIs.
redux wraps a reducer and initial state into a Zustand state creator. The resulting store exposes dispatch, which passes typed actions to the reducer; the reducer returns the next state.
redux<T, A extends { type: string }>(reducerFn: (state: T, action: A) => T, initialState: T): StateCreator<T & { dispatch: (action: A) => A }, [['zustand/redux', A]], []>| Name | Type | Description |
|---|---|---|
reducerFn | (state: T, action: A) => T | A pure function receiving the current state and an action, returning the next state. |
initialState | T | The value used as the initial state; it may have any type except function. |
A state creator function whose state includes dispatch for actions of type A.
import { create } from 'zustand'
import { redux } from 'zustand/middleware'
type State = { count: number }
type Action = { type: 'increment' | 'decrement'; by: number }
const reducer = (state: State, action: Action): State => {
switch (action.type) {
case 'increment': return { count: state.count + action.by }
case 'decrement': return { count: state.count - action.by }
}
}
const useStore = create(redux(reducer, { count: 0 }))
useStore.getState().dispatch({ type: 'increment', by: 2 })
console.log(useStore.getState().count)Creates a Zustand store whose reducer handles dispatched actions and updates the count.
An application already models state transitions as pure reducers and typed actions.
A team wants explicit action dispatch while using Zustand rather than a separate Redux store.
A vanilla Zustand store needs a reducer and dispatch API without React-specific state access.
redux middleware do?redux accepts a reducer and initial state, then returns a state creator. When an action is dispatched, the reducer receives the current state and action and returns the replacement state.
Follow-up: How is dispatch exposed? The middleware adds dispatch to the created Zustand state, and the vanilla store API also provides access to it.
The reducer should be pure: it takes the current application state and an action, then returns the new state produced by applying that action. The initial state supplies the store's starting value.
Follow-up: What constraint applies to initial state? Any value is allowed except a function, because the middleware treats the argument as state data.
The generic action type must include a string type property. The resulting state creator combines the state with a dispatch function that accepts that action type.
Follow-up: How would the action contract be enforced? Define a discriminated union or equivalent action type and annotate the reducer so unsupported action shapes fail type checking.
createcreateStoredispatchreducerzustand/middleware