Library & Framework/Zustand

[Zustand] Auto Generating Selectors 설정으로 더 간단하게 state값 가져오기

썸머워즈 2024. 4. 3. 10:40
반응형
"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

 

Zustand Documentation

Zustand is a small, fast and scalable bearbones state-management solution, it has a comfy api based on hooks

docs.pmnd.rs

 

반응형