Zustand采用发布订阅者模式,实现了createStore
方法
简易实现
下面实现一个简单的mini_createStore
方法,基于发布订阅
const mini_createStore = () => {
let state;
const listeners = new Set()
const getState = () => state
const setState = (newState) => {
state = newState
// * 通知订阅者
listeners.forEach(listener=>linstener())
}
// * 创建订阅方法
const subcribe = (listener) => {
// * 添加到订阅者列表中
listeners.add(listener)
// * 返回取消订阅的方法
return (listener) => listeners.delete(listener)
}
return {
getState,
setState,
subcribe
}
}
问题思考
这样简单的代码存在以下问题:
初始化问题
我们使用:
const store = mini_createStore()
后,再使用store.getState()
查看store
中state
的值
console.log(store.getState()) // undefined
会发现他是undefined
, but why?
因为我们在mini_createStore
中这样使用创建了state
let state
但是并没有初始化他,因此我们需要一个初始化方法。
此时我们让mini_createStroe
接受一个方法,用于初始化state
,如下:
const mini_createStore = (crateInitialState) => {
let state
const listeners = new Set()
const getState = () => state
const setState = (newState) => {
.....
}
const subcribe = (listener) => {
.............
}
// * 初始化state
state = crateInitialState()
return .....
}
现在我们已经可以正确的得到初始值啦:
const store = mini_createStore(()=>( {count: 0} ))
console.log(store.getState()) // * { count: 0 }
newState
方法问题
由于我们这样给state
赋值,
state = newState
有时我们期待使用方法来使用prevState
改变state
,如下:
store.setState((state) => ({ count: state.count + 1 }))
但是当我们打印store.getState()
得到:
console.log(store.getState()) // * [Function (anonymous)]
因此我们需要特判一下传入的newState
类型,如下:
state = typeof newState === "Function" ? newState(state) : newState
现在我们已经可以通过方法来改变state
啦
const store = mini_createStore(() => ({ count: 0 }))
store.setState((state) => ({ count: state.count + 1 }))
console.log(store.getState()) // * { count: 1}