zustand로 모달 관리하기리액트에서 zustand로 Map 객체를 사용하여 모달 전역 관리 하는 방법에 대해 알아봅니다.
frontend
24.02.20
6 min read
authors
createDate
Feb 20, 2024
status
Public
category
frontend
summary
리액트에서 zustand로 Map 객체를 사용하여 모달 전역 관리 하는 방법에 대해 알아봅니다.
slug
managing-modal-with-zustand

개요

사이드 프로젝트를 하던, 사내 프로젝트를 진행하던 모달을 항상 사용하고 있습니다. 하지만 모달을 사용할수록 좋은 방식에 대해 고민이 많아지더라고요. 현재는 몇 달 전에 본 게시글을 바탕으로 제 환경에 맞게 변경해 사용하는 중입니다. 진행중인 몇몇 프로젝트에서 잘 사용하고 있어서, 기본적인 세팅을 저장 해놓고 이후 프로젝트를 시작할때도 참고하려고 합니다.
예시는 vite, react-router-dom, zustand, shadcn-ui 환경에서 진행했습니다.

코드

모달 상태를 관리하는 코드(store), 모달을 렌더링하는 코드(provider), 모달 UI 코드(modal) 세 부분으로 나누어 관리합니다.

1. 모달 상태를 관리하는 Store 생성

  • 모달 컴포넌트를 담는 배열과 모달을 열고 닫는 함수를 관리하는 Store를 생성합니다.
  • 모달의 open 여부를 확인하는 boolean값은 스토어 내의 액션 함수에서 주입합니다.

2. 모달을 렌더링 하는 Provider 컴포넌트 생성

  • 모달의 open값을 false로 바꿔주는 onCloseModal함수와 모달을 배열에서 지워주는 onCleanModal함수를 사용하여 onClose 함수를 만든 후 컴포넌트의 props로 주입합니다.
    • 이렇게 한 이유는 모달이 바로 배열에서 지워지면 모달의 close animation이 작동하지 않기 때문입니다.
  • pathnameuseEffect의 의존성 배열에 담아, 만약 모달이 열린채로 라우트 이동이 발생한다면 배열을 비워주는 onResetModal함수를 호출합니다.

3. 모달 생성

  • Store에서 주입한 open 값과 Provider에서 주입한 onClose 함수에 대한 타입을 작성합니다.

4. 모달 Provider 적용 및 모달 호출하기

  • ModalProvider를 최상단 파일에 작성합니다.
  • onOpenModal로 모달을 호출합니다. 첫번째 인자로 컴포넌트를 넘기고, 두번째 인자는 선택적으로 props를 넘깁니다.

장단점

이 방식으로 모달을 관리하면 어떤 장단점이 있을까요? 제가 사용하면서 느낀점을 적어보겠습니다.

장점

  • open값과 onClose함수를 중앙에서 관리합니다
모든 모달에 필요한 open값을 Store의 액션 함수에서 주입하고, onClose함수를 Provider에서 작성해 모달의 props로 넘기기 때문에 로직 반복을 줄일 수 있습니다.
  • 기능별로 분리해서 관리합니다
상태 관리, 렌더링, UI 코드를 각각 분리해서 작성하기 때문에 상황에 맞게 필요한 코드만 보고 파악이 가능합니다.
  • Map 객체로 관리합니다
키 값을 사용하여 검색(has), 삽입(set), 삭제(delete) 등을 효율적으로 할 수 있습니다. size메서드를 사용해 길이 파악도 가능합니다.

단점

  • closeModalcleanModal이 분리되어 있습니다
우선 모달의 open값을 false로 바꾼 후에, cleanModal을 통해 Map객체에서 모달을 제거합니다. 왜 맵에서 바로 모달을 제거하지 않았을까요? 이유는 모달이 닫힐때 애니메이션의 작동 때문입니다. 바로 맵에서 제거하게 되면 닫히는 애니메이션이 동작하지 않더라고요. DOM에서 제거되기 전에, exit animation을 동작시키는 방법을 찾아봐야할 것 같습니다.
  • 필요한 코드가 많습니다
초반에 필요한 코드가 많다보니 새로 프로젝트에 들어갈때 매번 코드를 작성하는게 꽤 번거롭습니다. 모달 컴포넌트 자체에서 Trigger와 Contents를 전부 작성하면 파일 하나로 끝나는데 말이죠. 이 단점을 보완하기 위해 이 글을 남기는 것이기도 합니다.

마치며

완벽한 방식은 아니겠지만 나름 만족하면서 사용중입니다. 하지만 누군가에게 이 방식을 직접 설명하면서 공유한적은 없는데요. 글을 읽어주시는 분들의 날카로운 피드백을 기대하고 있겠습니다.
궁금한 점이나, 오류가 있다면 편하게 댓글 남겨주세요!

레퍼런스

  • 정말 도움이 많이 된 글입니다. 직접 읽어보시는걸 강추합니다!