一、中间件代码
// 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;相当于重写api的setState方法;修改值时调用pruduce生成新值,调用apisetState方法
源码中
initializer函数(对应实例中immer参数)调用把api.setState即set参数传给return对象(闭包)
需要特别注意的是immer函数的
setState其实不是订阅器setState而是api的setState