저번글에서 설명한 토이프로젝트2(일정관리,급여)에서 저는 일정관리 파트를 맡게 되었습니다.
일정관리 파트에서 처음 기획하는 단계에서는 react-canledar 라이브러리를 이용하여 첫 렌더링 시 등록된 일정들을 한눈에 알아볼 수 있도록 기능을 구현하는 처음 목표로 가져갔습니다.
그렇게 기획하는 중 직원들을 관리하는 총 관리자가 모든 직원들에 대한 일정을 확인하고 추가,수정,삭제를 할 수 있어야한다고 판단하여 사용자를 구분지어 사용자 postion에 따른 관리자와 사용자의 UI를 분리하여 만들게 되었습니다.
저의 경우에는 일정 관리 파트에서도 관리자 부분을 맡아서 진행하고 있으며 관리자의 경우에는 사용자와 다르게 각자의 개인 일정을 관리하는 것이 아닌 직원 전체에 대한 일정을 관리할 수 있도록 하여야하기 때문에 데이터를 받아오는 단계에서 좀 더 다양한 처리가 필요했습니다.
이 단계에 firebase의 경우 로그인한 사용자 즉, 자기 자신만의 authuserId만 가져올 수 있기 때문에 관리자에서 모든 추가하고자하는 userId를 가져오기 어렵다고 판단하여 firebase에서 superbase로 다시 마이그레이션을 진행하였습니다.
그리고 프론트엔드 코드가 주가 아니라 firbase에서 가져오는 데이터를 기준으로 코드가 작성되다보니 너무 종속된다는 생각도 가지게 되었습니다.
관리자의 경우에는 모든 직원에 대한 데이터를 가져와서 해당하는 직원을 선택하고 선택한 직원에 대한 일정을 추가하도록 기능을 구현하고 있습니다.
캘린더에서 해당 날짜를 클릭하면 카드형식으로 날짜에 해당 모든 직원에 일정 볼 수 있고 수정과 삭제는 아이콘을 통해 Modal(Portal)을 통해 수정, 삭제 할 수 있도록 하였습니다.
간략하게 일반적인 Modal 구현과 react.Protal의 장단점을 비교 해보도록 하겠습니다.
DOM 구조의 독립성: 컴포넌트를 DOM 트리의 다른 위치에 렌더링할 수 있어 부모 컴포넌트의 구조에 영향을 받지 않습니다
스타일링 용이성: overflow: hidden이나 z-index와 같은 부모 컴포넌트의 스타일 속성에 영향을 받지 않아 스타일링이 더 쉽습니다
접근성 향상: 모달이나 오버레이와 같은 요소를 의미론적으로 올바른 위치에 배치할 수 있어 스크린 리더와 같은 접근성 도구에 더 적합합니다
코드 가독성 향상: HTML 구조가 더 간결해지고 보기 좋아집니다2.
예시 코드는 아래와 같습니다.
<!-- index.html -->
<div id="root"></div> <!-- React app이 렌더링되는 기본 div -->
<div id="modal-root"></div> <!-- Portal을 위한 추가 div -->
위 코드를 보시면 root
영역이 아닌 새로운 Portal을 위한 div
를 추가합니다.
import { ReactNode } from 'react';
import { createPortal } from 'react-dom';
const ModalPortal = ({ children }: { children: ReactNode }) => {
const modalRoot = document.getElementById('modal') as HTMLElement;
return createPortal(children, modalRoot);
};
export default ModalPortal;
<ModalPortal>
<Modal>
</ModalPortal>
위 코드처럼 다양한 모달을 만들고 ModalPortal
로 감싸줌으로써 재사용을 높일 수 있도록 코드를 구현하였습니다.