可调试的demo案例具体实现
整个zustand的核心部分。
可以拆成两块实现:
- 1、核心store对象 —— createStore(创造一个store实例)
- 2、将store的变更同步给React,让他更新。 —— useStore(暴露出state快照)
如何链接 store 和 react呢?
react 提供了 useSyncExternalStore 这么一个Hook。 从英文上理解一下, “同步使用外部的store”
然后我们看一下官网(zh-hans.react.dev/reference/r…
参数:
- 1、subscribe 函数应当订阅该 store 并返回一个取消订阅的函数。
- 2、getSnapshot 函数应当从该 store 读取数据的快照。
我们能够从 subscribe 里拿到订阅者的信息,将它们都收集起来。而每次的store状态就由getSnapshot 传给react。 所以我们在createStore 提供两个方法 subscribe 和 getStore ,订阅 和 拿到当前值。
import React from 'react'
/**
* 整个zustand的核心部分。
* 可以拆成两块实现:
* 1、核心store对象 —— createStore(创造一个store实例)
* 2、将store的变更同步给React,让他更新。 —— useStore(暴露出state快照)
*
* 如何链接 store 和 react呢?
* react 提供了 useSyncExternalStore 这么一个Hook。
* 从英文上理解一下, “同步使用外部的store”
*
* 然后我们看一下官网(https://zh-hans.react.dev/reference/react/useSyncExternalStore)
* 参数:
* 1、subscribe 函数应当订阅该 store 并返回一个取消订阅的函数。
* 2、getSnapshot 函数应当从该 store 读取数据的快照。
*
* 因此我们能够从 subscribe 里拿到订阅者的信息,将它们都收集起来。
*/
// 1、核心store对象
// 整个store作为一个观察者
const createStore = (createState) => {
let state
const listeners = new Set() // 订阅者
// 仿照 setState 的执行实现
const setState = (partial) => {
console.log(state)
const nextState = typeof partial === 'function' ? partial(state) : partial
if(!Object.is(nextState, state)) {
const preveState = state
// 每次都产生一个新的对象,来保证快照不同。(核心因为react以Object.is方法来判断的)
state = Object.assign({}, state, nextState)
// 更新时,通知所有订阅者
listeners.forEach(listener => listener(state, preveState))
}
}
const getState = () => state
const subscribe = (listener) => {
listeners.add(listener)
return () => {
listeners.delete(listener)
}
}
const getInitialState = () => initialState
const api = { setState, getState, getInitialState, subscribe }
const initialState = (state = createState(setState, getState, api))
return api
}
// 2、 具体链接的实现
const useStore = (api, selector) => {
const subscribe = api.subscribe
if(!selector) selector = (state) => state
const slice = React.useSyncExternalStore(subscribe, () => selector(api.getState()), () => selector(api.getState()))
return slice
}
const createImpl = (createState) => {
// 第一步
const api = createStore(createState)
// 第二步
const useBoundary = (selector) => useStore(api, selector)
return useBoundary
}
export const create = (createState) => typeof createState === 'function' ? createImpl(createState) : createImpl