跳到主要内容

模拟实现

2024年02月26日
柏拉文
越努力,越幸运

一、实现


1.1 create()

export const create = (createState) => createState
? createImpl(createState)
: createImpl

1.2 createImpl()

const createImpl = (createState) => {
const api = typeof createState === 'function'
? createStore(createState)
: createState

const useBoundStore = (selector, equalityFn) =>
useStore(api, selector, equalityFn)

Object.assign(useBoundStore, api)

return useBoundStore
}

1.3 createStore()

export const createStore = ((createState) =>
createState ? createStoreImpl(createState) : createStoreImpl) as CreateStore

1.4 createStoreImpl()

const createStoreImpl: CreateStoreImpl = (createState) => {
let state;
const listeners = new Set();

const setState = (partial, replace) => {
const nextState =
typeof partial === 'function'
? partial(state)
: partial
if (!Object.is(nextState, state)) {
const previousState = state
state =
replace ?? (typeof nextState !== 'object' || nextState === null)
? (nextState as TState)
: Object.assign({}, state, nextState)
listeners.forEach((listener) => listener(state, previousState))
}
}

const getState = () => state

const getInitialState= () =>
initialState

const subscribe = (listener) => {
listeners.add(listener)
return () => listeners.delete(listener)
}

const destroy = () => {
listeners.clear()
}

const api = { setState, getState, getInitialState, subscribe, destroy }
const initialState = (state = createState(setState, getState, api))
return api
}

1.5 useStore()

export function useStore(
api,
selector,
equalityFn,
) {
const slice = useSyncExternalStoreWithSelector(
api.subscribe,
api.getState,
api.getServerState || api.getInitialState,
selector,
equalityFn,
)
return slice
}

二、测试