zustand immer中间件

255 阅读1分钟

一、中间件代码

// set方法是订阅器setState,和下面api setState不一定一致
const immerImpl: ImmerImpl = (initializer) => (set, get, store) => {
  type T = ReturnType<typeof initializer>
  // 修改api setState方法
  store.setState = (updater, replace, ...a) => {
    const nextState = (
      typeof updater === 'function' ? produce(updater as any) : updater
    ) as ((s: T) => T) | T | Partial<T>
    // 最终还是调用发布订阅器的set方法
    return set(nextState as any, replace, ...a)
  }
  // 这段代码是为了createStoreImpl函数获取最新state;
  // const initialState = (state = createState(setState, getState, api))
  return initializer(store.setState, get, store)
}

export const immer = immerImpl as unknown as Immer

二、使用实例

export const useCountStore = create<State & Actions>()(
  immer((set) => ({
    count: 0,
    increment: (qty: number) =>
      set((state) => {
        state.count += qty
      }),
    decrement: (qty: number) =>
      set((state) => {
        state.count -= qty
      }),
  }))
)

1.immer调用一个函数

就一个闭包作用,immer参数即源码中的initializer

2.create函数调用

immer返回值作为create函数入参,store就是源码篇的api;相当于重写apisetState方法;修改值时调用pruduce生成新值,调用api setState方法

源码中initializer函数(对应实例中immer参数)调用把api.setState即set参数传给return对象(闭包)

需要特别注意的是immer函数的setState其实不是订阅器setState而是api的setState