zustand를 그냥 사용했을 때 문제점
zustand를 각각의 slice로 관리하다보면 다음의 단점이 있습니다.
- 각각의 store에서 상태를 가져와야하기 때문에 import와 const 선언문이 길어집니다.
- 각각의 store에 속해있는 상태값을 서로 참고하거나 가져올 수 없습니다.
use_store 훅을 통한 중앙 집중식 관리
백화점을 떠올리면 좋을 것 같습니다. 각각의 store를 use_store에 입점시켜 서로를 참조하고, 함께 가져올 수 있도록 합니다.
기본 구조는 zustand의 공식문서를 참고하여 작성하였습니다.
또, 휘발 될 수 있는 상태값을 localStorage에 저장하여 재사용성을 높였습니다.
use_store의 형태
import type { TCartSlice } from "@/stores/cart_store";
import { create } from "zustand";
import { createCartSlice } from "@/stores/cart_store";
import { createSelectorFunctions } from "auto-zustand-selectors-hook";
import { persist, createJSONStorage, subscribeWithSelector } from "zustand/middleware";
const storage: StateStorage = {
removeItem: async (name: string): Promise<void> => {
window.localStorage.removeItem(name);
},
setItem: async (name: string, value: string): Promise<void> => {
window.localStorage.setItem(name, JSON.parse(value));
},
getItem: async (name: string): Promise<string | null> => {
const value = window.localStorage.getItem(name);
return value !== undefined ? JSON.stringify(value) : null;
},
};
export type State = TCartSlice;
export const useStore = create<State>()(
subscribeWithSelector(
persist(
(...a) => ({
...createCartSlice(...a),
}),
{
version: 144,
name: "haru-damu",
storage: createJSONStorage(() => storage),
partialize: (keys) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { ...persistData } = keys;
return persistData;
},
},
),
),
);
export const selector = createSelectorFunctions(useStore);
사용 예시
// use_store를 불러와 한번에 선언 할 수 있습니다.
import { useStore } from "@/hooks/usestore";
const { cart, getIsCheckedAllCartItems, changeIsCheckedAllCartItems, bulkAddMealCartItems, getCheckedCartItems } =
useStore();
// 각각의 store에서 get()을 통해 서로를 참조하여 사용 할 수 있습니다.
getCartItem: () => {
return get().user?
},