React -> nextJS로 전환하면서 리덕스를 걷어내고 useSWR로 데이터를 관리하고 있는중
글로벌 상태 관리는 Context API를 사용하자! 라고 생각하여 개발하였습니다.
새로 입사한 개발자분이 페이지 하나를 담당하여 개발중 최상위 컴포넌트에 1개의 Context Provider를 설정하여
개발을 진행하였고 역시나 엄청난 리렌더링 덕분에 개발자 도구 네트워크에 찍힌 같은 URL데이터 호출이 5번정도
혹은 어떠한 이벤트를 실행할 때 마다 네트워크를 호출하는 문제가 발생하였습니다.
이 문제를 해결을 하기 위해서는 context api를 분할하여 관리를 해야한다고 피드백을 주었지만
당사자는 이미 너무 먼길을 와서 처음부터 개발을 해야할 거 같다는 말씀을 하셨다...
그러던중 zustand를 알았고 공식 문서를 확인하니 context api의 불필요한 리렌더링의 단점을 보완한 라이브러리였고
사용방법도 훅을 사용하여 진짜 정말 완전 간편하게 사용할 수 있어 바로 개발자분에게 말씀드리고 그것을 적용하였다.
공식 깃허브 사이트가 있기 때문에 링크를 올려두겠습니다.
https://github.com/pmndrs/zustand#transient-updates-for-often-occuring-state-changes
여러 zustand 상태중 정말 간단히 작성한 코드로 소개 하겠습니다.
useOptionsState.ts 파일 생성후
import create from 'zustand';
//타입 설정
export interface OptionState {
currentProduct: string;
requiredOptions: string[];
setCurrentProduct: (value: string) => void;
setRequiredOptions: (value: string[]) => void;
}
//기본 상태 선언
const defaultState = {
currentProduct: '',
requiredOptions: [],
};
export const useOptionState = create<OptionState>(set => ({
...defaultState,
setCurrentProduct: value => set(() => ({ currentProduct: value })),
setRequiredOptions: value => set(() => ({ requiredOptions: value })),
}));
사실 공식 문서를 보면 설명 할 것도 없이 너무 간단한 코드이다.
바로 다음으로 넘어가겠습니다.
OptionModal.tsx 컴포넌트에서 zustand를 사용 해보겠습니다.
import { useOptionState } from '@hooks/option/useOptionState';
const [currentProduct, setCurrentProduct] = useOptionState(state => [state.currentProduct, state.setCurrentProduct], shallow);
const [requiredOptions, setRequiredOptions] = useOptionState(state => [state.requiredOptions, state.setRequiredOptions], shallow);
사실
const [currentProduct, setCurrentProduct, requiredOptions, setRequiredOptions] = useOptionState(
state => [state.currentProduct, state.setCurrentProduct, state.requiredOptions, state.setRequiredOptions],
shallow,
);
이런식으로 한번에 선언하여 사용이 가능하지만 보다시피 4개이상만 되어도 코드가 길어지고 가독성이 떨어지기 때문에
우리팀은 이런식으로 useState 비슷한 모양처럼 사용중입니다.