본문 바로가기
개발/React

zustand에서 functional update가 가능한 setState만들기

by 안뇽! 2023. 11. 6.
반응형

useState의 setState는 다음과 같이 이전값을 통한 functional update가 가능하다.

    setIcons(prev => {
        const updatedIcons = prev.map(i => {
            if (i.id === icon.id) {
                return { ...i, alt: e.target.value };
            }
          return i;
        });
        return updatedIcons;
    });

 

state를 전역으로 관리하기 위해 zustand를 이용할때가 있는데, 지금까지는 zustand에서 setState를 다음과 같이 만들었었다.

import { IconType } from '@/components/Icon';
import { create } from 'zustand';

interface UnderbarStoreProps {
  iconsOnUnderbar: IconType[];
  setIconsOnUnderbar: (icon: IconType[]) => void;
}

export const useUnderbarStore = create<UnderbarStoreProps>(set => ({
  iconsOnUnderbar: [],
  setIconsOnUnderbar: (iconsOnUnderbar: IconType[]) => set({ iconsOnUnderbar }),
}));

 

이는 완벽한 setState가 아니다. funtional update를 할 수 없기 떄문이다.

setIconsOnUnderbar([]) //가능
setIconsOnUnderbar(prev=>prev.map(i=>....)) // functional update 불가능, 
// prev' 매개 변수에는 암시적으로 'any' 형식이 포함됩니다.ts(7006)
//'(prev: any) => any' 형식의 인수는 'IconType[]' 형식의 매개 변수에 할당될 수 없습니다.ts(2345)

 

functional update를 가능하게 하려면 다음과 같이 만들어야 한다.

import { IconType } from '@/components/Icon';
import { SetStateAction } from 'react';
import { create } from 'zustand';

interface UnderbarStoreProps {
  isModalOpen: boolean;
  setIsModalOpen: (isNavOpen: boolean) => void;
  iconsOnUnderbar: IconType[];
  setIconsOnUnderbar: (prev: SetStateAction<IconType[]>) => void;
}

export const useUnderbarStore = create<UnderbarStoreProps>(set => ({
  isModalOpen: false,
  setIsModalOpen: (isModalOpen: boolean) => set({ isModalOpen }),
  iconsOnUnderbar: [],
  setIconsOnUnderbar: (prev: SetStateAction<IconType[]>) => {
    prev instanceof Function
      ? set(state => ({ iconsOnUnderbar: prev(state.iconsOnUnderbar) }))
      : set({ iconsOnUnderbar: prev });
  },
}));
반응형