모달 상태 관리 코드를 리팩토링하다가, zustand에서 store를 어떻게 구독하는 게 더 좋은지 고민하는 과정이 있었다.
공식 문서에도 있는 내용이었으나 구현에 급급해서 공부가 소홀했다
// stores/modalStore.ts
import create from 'zustand';
interface ModalState {
isOpen: boolean;
open: () => void;
close: () => void;
}
export const useModalStore = create<ModalState>(set => ({
isOpen: false,
open: () => set({ isOpen: true }),
close: () => set({ isOpen: false }),
}));
이건 모달 상태를 간단하게 zustand로 전역관리 하는 modal 전용 store인데 (공용 modal 컴포넌트와 묶어서 사용중)
기존에는 간략하게 작성하려고 아래와 같이 사용했으나
const { isOpen, open, close } = useModalStore();
이건 store 전체를 구독하는 비효율적 패턴이라고 한다, - store 내 다른 값이 바뀌어도 이 컴포넌트가 리렌더링되기 때문.
특히 규모가 커질수록 불필요한 렌더가 많아져서 퍼포먼스에 악영향을 줄 수 있다고한다
(2) selector로 필요한 값만 개별 구독 – 권장 패턴
const isOpen = useModalStore(state => state.isOpen);
const { open, close } = useModalStore(state => ({
open: state.open,
close: state.close,
}));
이와 같이 개별구독할 시 isOpen이 바뀔 때만 리렌더링이 발생한다.
(open/close는 변하지 않는 함수이니 한번에 불러와도 성능상 문제는 없을 것으로 예상된다
(3) 여러 값을 한 번에 selector로
const { isOpen, open, close } = useModalStore(state => ({
isOpen: state.isOpen,
open: state.open,
close: state.close,
}));
이 방식은 store 전체 구독보단 낫지만, selector 안의 값 중 하나라도 바뀌면 매번 새로운 객체가 리턴되어(참조값 변화), 해당 컴포넌트가 리렌더된다.
=> 상태(state) 값은 개별 selector / 액션(action) 함수들은 묶어서 selector로 한 번에
참고 문서
'today,weekly I learn' 카테고리의 다른 글
ID 기반 공용 Modal 컴포넌트 구현하기(+id 하드코딩 방지) (0) | 2025.06.29 |
---|---|
CodeRabbit ai 사용기 (1) | 2025.06.16 |
왜 내 모달은 리사이즈 때마다 닫힐까 - 리사이징,상태 초기화 문제와 단일 트리 + CSS 리팩터링 과정 (0) | 2025.06.11 |
리액트 렌더링에 대해서 (0) | 2025.04.16 |
클라이언트 컴포넌트는 서버 컴포넌트를 직접 import 할 수 없음 (Next.js) (0) | 2025.04.06 |