반응형
"react": "^18.2.0",
"zustand": "^4.5.2"
"typescript": "^5.2.2",
Auto Generating Selectors
공식문서에서 제공하는 선택기 자동 생성 패턴이다.
const count = useCountStore((state) => state.count)
보통 이런 식으로 state값을 가져오기는 하는데 state => state.count 이런 방식조차 너무 자주쓰면 귀찮긴 하다.
훌륭하게도 zustand쪽에서 자동으로 실렉터를 생성해 주는 방식을 제공해 주어 그대로 적용해 보자.
store/index.ts
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
) => {
let store = _store as WithSelectors<typeof _store>
store.use = {}
for (let k of Object.keys(store.getState())) {
;(store.use as any)[k] = () => store((s) => s[k as keyof typeof s])
}
return store
}
export default createSelectors
index 쪽에 Auto Generating Selectors를 지정해 두고 스토어에 감싸서 사용해 주면 된다.
이는 공식문서에서 제공해주고 있는 코드를 그대로 가져와 설정해준것이다.
store/countStore.ts
import createSelectors from '@/store'
import { create } from 'zustand'
import { devtools } from 'zustand/middleware'
type TCountStore = {
count: number
actions: {
increase: () => void
decrease: () => void
}
}
const useCountStoreBase = create<TCountStore>()(
devtools((set) => ({
count: 0,
actions: {
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
},
}))
)
export const useCountStore = createSelectors(useCountStoreBase)
이런 식으로 생성한 스토어를 createSelectors에 한 번 감싸주면 끝이다.
CountView.tsx
import { useCountStore } from '@/store/countStore'
const CountButton = () => {
// get the action
const { increase, decrease } = useCountStore.use.actions()
return (
<>
<button onClick={increase}>증가</button>
<button onClick={decrease}>감소</button>
</>
)
}
const Count = () => {
// get the property
const count = useCountStore.use.count()
return <div>{count}</div>
}
export default function CountView() {
return (
<>
<Count />
<CountButton />
</>
)
}
사용할 때는 store.use.(가져오려는 state값)으로 아주 간단하게 가져와 사용이 가능하다.
참고: https://docs.pmnd.rs/zustand/guides/auto-generating-selectors
반응형
댓글