mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
[v5]: do not depend on use-sync-external-store (#2301)
* [v5]: do not depend on use-sync-external-store * memo get(server)snapshot
This commit is contained in:
parent
e5b64ccc19
commit
6c9944b2c8
34
src/react.ts
34
src/react.ts
@ -1,12 +1,9 @@
|
||||
// import { useDebugValue } from 'react'
|
||||
// import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'
|
||||
// Those don't work in ESM, because React libs are CJS only.
|
||||
// import { useDebugValue, useSyncExternalStore } from 'react'
|
||||
// That doesn't work in ESM, because React libs are CJS only.
|
||||
// See: https://github.com/pmndrs/valtio/issues/452
|
||||
// The following is a workaround until ESM is supported.
|
||||
// eslint-disable-next-line import/extensions
|
||||
import ReactExports from 'react'
|
||||
// eslint-disable-next-line import/extensions
|
||||
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector'
|
||||
import { createStore } from './vanilla.ts'
|
||||
import type {
|
||||
Mutate,
|
||||
@ -15,8 +12,7 @@ import type {
|
||||
StoreMutatorIdentifier,
|
||||
} from './vanilla.ts'
|
||||
|
||||
const { useDebugValue } = ReactExports
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports
|
||||
const { useDebugValue, useMemo, useSyncExternalStore } = ReactExports
|
||||
|
||||
type ExtractState<S> = S extends { getState: () => infer T } ? T : never
|
||||
|
||||
@ -24,6 +20,23 @@ type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>
|
||||
|
||||
const identity = <T>(arg: T): T => arg
|
||||
|
||||
const useMemoSelector = <TState, StateSlice>(
|
||||
getState: () => TState,
|
||||
selector: (state: TState) => StateSlice,
|
||||
) =>
|
||||
useMemo(() => {
|
||||
let lastSlice: StateSlice
|
||||
let lastState: TState
|
||||
return () => {
|
||||
const state = getState()
|
||||
if (!Object.is(lastState, state)) {
|
||||
lastSlice = selector(state)
|
||||
lastState = state
|
||||
}
|
||||
return lastSlice
|
||||
}
|
||||
}, [getState, selector])
|
||||
|
||||
export function useStore<S extends StoreApi<unknown>>(api: S): ExtractState<S>
|
||||
|
||||
export function useStore<S extends StoreApi<unknown>, U>(
|
||||
@ -35,11 +48,10 @@ export function useStore<TState, StateSlice>(
|
||||
api: StoreApi<TState>,
|
||||
selector: (state: TState) => StateSlice = identity as any,
|
||||
) {
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
const slice = useSyncExternalStore(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getInitialState,
|
||||
selector,
|
||||
useMemoSelector(api.getState, selector),
|
||||
useMemoSelector(api.getInitialState, selector),
|
||||
)
|
||||
useDebugValue(slice)
|
||||
return slice
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user