zustand는 사용방법은 간단하지만, 다양한 방식으로 응용이 가능하며, 사용하는 사람에 따라 방식이 천차만별이다. 최적의 방법을 찾다가 알게된 방법들을 정리해본다.
참고 : Working with Zustand
전체 스토어를 구독하게 되면, 스토어에 담고 있는 모든 state가 변경될 때마다 구독중인 컴포넌트가 불필요하게 렌더링됨.
—> 스토어는 작게, 모듈단위로 분리하는것이 좋다.
—> 스토어 전체구독이 아닌, 필요한 state만 구독해서 사용할것.
// 전체 스토어를 구독 --> 불필요한 리렌더링 발생
const {dataTextTemp} = useStudioStore()
// 필요한 state만 구독 --> 해당 state변경시에만 리렌더링 발생
export const useBears = () => useBearStore((state) => state.bears)
shallow
기능 : 해당 스테이트의 값이 이전값과 다른지 비교후 달라졌을 때만 렌더링을 시켜준다. import shallow from 'zustand/shallow'
// ⬇️ much better, because optimized
const { bears, fish } = useBearStore(
(state) => ({ bears: state.bears, fish: state.fish }),
shallow
)
const useBearStore = create((set) => ({
bears: 0,
fish: 0,
// ⬇️ separate "namespace" for actions
actions: {
increasePopulation: (by) =>
set((state) => ({ bears: state.bears + by })),
eatFish: () => set((state) => ({ fish: state.fish - 1 })),
removeAllBears: () => set({ bears: 0 }),
},
}))
export const useBears = () => useBearStore((state) => state.bears)
export const useFish = () => useBearStore((state) => state.fish)
// 🎉 one selector for all our actions
export const useBearActions = () => useBearStore((state) => state.actions)
꺼내쓰는 경우
const { increasePopulation } = useBearActions() //하나의 훅에서 꺼내써도 됨.
import { create } from 'zustand'
import { createRef } from 'react'
import { EditorType } from '@/components/newFile/EditorType'
interface State {
initialData: string
tooltipPosition: { x: number; y: number }
}
interface Action {
setInitialData: (data: string) => void
setTooltipPosition: (x: number, y: number) => void
}
const initialState: State = {
initialData: null,
tooltipPosition: { x: 0, y: 0 },
}
export const useStudioStore = create<State & Action>((set, get) => ({
...initialState,
setTooltipPosition: (x: number, y: number) => set({ tooltipPosition: { x, y } }),
setInitialData: (data: string) => set({ initialData: data }),
setShowTutorial: (show: boolean) => set({ showTutorial: show }),
setInitialized: (initialized: boolean) => set({ initialized: initialized }),
setEditorRef: (ref) => set({ editorRef: { current: ref } }),
setFileTitle: (title) => set({ fileTitle: title }),
setIsSubmitted: (isSubmitted: boolean) => set({ isSubmitted: isSubmitted }),
}))