import { StoreApi, UseBoundStore } from 'zustand'
type WithSelectors<S> = S extends { getState: () => infer T }
? S & { use: { [K in keyof T]: () => T[K] } }
: never
const createSelectors = <S extends UseBoundStore<StoreApi<object>>>(
_store: S,
) => {
const store = _store as WithSelectors<typeof _store>
store.use = {}
for (const k of Object.keys(store.getState())) {
;(store.use as any)[k] = () => store((s) => s[k as keyof typeof s])
}
return store
}
import { StoreApi, useStore } from 'zustand'
type WithSelectors<S> = S extends { getState: () => infer T }
? S & { use: { [K in keyof T]: () => T[K] } }
: never
const createSelectors = <S extends StoreApi<object>>(_store: S) => {
const store = _store as WithSelectors<typeof _store>
store.use = {}
for (const k of Object.keys(store.getState())) {
;(store.use as any)[k] = () =>
useStore(_store, (s) => s[k as keyof typeof s])
}
return store
}
const useBearStore = createSelectors(useBearStoreBase)
// get the property
const bears = useBearStore.use.bears()
// get the action
const increment = useBearStore.use.increment()
;
in front of a line of code is to prevent JavaScript from mistaking it for a function callconst x = 5
(function () {
console.log('oops')
})()
const x = 5(function () { // <- treated as a function call on 5!
console.log('oops')
})()
S
is type for Store
T
is type for State
T
- a plain object of our declared data and actionsexport const useBoundStore = create((set) => ({
count: 0,
text: 'hello',
inc: () => set((state) => ({ count: state.count + 1 })),
setText: (text) => set({ text }),
}))
export const useBoundStore = create(() => ({
count: 0,
text: 'hello',
}))
export const inc = () =>
useBoundStore.setState((state) => ({ count: state.count + 1 }))
export const setText = (text) => useBoundStore.setState({ text })