• 简体中文
  • 受 Flux 启发的实践

    尽管 Zustand 是一个不强加约定的库,但我们确实推荐一些模式。 这些模式受最初出现于 Flux 的实践启发, 后来也受 Redux 中的实践启发, 因此如果你来自其他库,应该会感到很亲切。

    不过,Zustand 在一些根本层面确实有所不同, 因此某些术语可能无法与其他库完全对应。

    推荐模式

    单一 store

    应用的全局状态应放在单个 Zustand store 中。

    如果你的应用规模较大,Zustand 支持将 store 拆分为多个切片。

    使用 set / setState 更新 store

    务必使用 set(或 setState)来更新你的 store。 set(以及 setState)会确保所描述的更新被正确合并,并恰当地通知监听者。

    就近放置 store action

    在 Zustand 中,更新状态无需像其他 Flux 库那样使用派发的 action 和 reducer。 这些 store action 可以直接添加到 store 中,如下所示。

    可选地,借助 setState,它们也可以放在 store 外部

    const useBoundStore = create((set) => ({
      storeSliceA: ...,
      storeSliceB: ...,
      storeSliceC: ...,
      updateX: () => set(...),
      updateY: () => set(...),
    }))

    类 Redux 模式

    如果你离不开类 Redux 的 reducer,可以在 store 的根层级定义一个 dispatch 函数:

    const types = { increase: 'INCREASE', decrease: 'DECREASE' }
    
    const reducer = (state, { type, by = 1 }) => {
      switch (type) {
        case types.increase:
          return { grumpiness: state.grumpiness + by }
        case types.decrease:
          return { grumpiness: state.grumpiness - by }
      }
    }
    
    const useGrumpyStore = create((set) => ({
      grumpiness: 0,
      dispatch: (args) => set((state) => reducer(state, args)),
    }))
    
    const dispatch = useGrumpyStore((state) => state.dispatch)
    dispatch({ type: types.increase, by: 2 })

    你也可以使用我们的 redux-middleware。它会接上你的主 reducer、设置初始状态,并把 dispatch 函数添加到状态本身以及原生 API 上。

    import { redux } from 'zustand/middleware'
    
    const useReduxStore = create(redux(reducer, initialState))

    更新 store 的另一种方式,是用函数包装状态函数。这些函数还可以处理 action 的副作用,例如进行 HTTP 调用。若要以非响应式方式使用 Zustand,请参阅 readme。