모달 구현 시 고려해야 할 사항

들어가며
최근에 UI를 직접 구현하는 스터디에 참여하게 되었다. 첫 번째 주제로 모달 UI를 다루게 되었고, 간단한 모달을 구현하며 모달의 기능과 동작 방식을 살펴보았다. 이 과정에서 모달을 구현할 때 고려해야 할 부분을 알게 되어 정리해 보았다.
모달이란?
모달은 페이지 주요 콘텐츠에 대한 추가 정보를 제공하거나 사용자의 액션을 유도하기 위해서 페이지 위에 오버레이 형태로 표시되는 UI 컴포넌트다.
모달의 일반적인 특징
유저가 버튼을 클릭하면 모달이 나타난다.
모달은 부모 컴포넌트의 구조와 스타일에 영향을 받지 않도록 독립적으로 동작해야 한다.
모달은 배경을 흐릿하게(dimmed) 처리하여 사용자의 집중도를 높인다.
이제 이번에 간단한 모달 구현했을 때 고려했던 부분을 살펴보자.
간단한 모달 구현시 고려했던 사항들
createPortal을 사용한 렌더링
createPortal
을 사용하여 모달이 DOM 계층 구조를 벗어나document.body
에 렌더링되도록 처리했다. 이 방식으로 부모 컴포넌트에 영향받지 않고 독립적으로 동작할 수 있었다.
Controlled 컴포넌트 방식 적용
- 모달의 상태(
open
,onClose
)를 부모 컴포넌트에서 전달받도록 설계했다. 부모의 상태 변경을 그대로 사용해서 일관되게 모달을 제어할 수 있도록 했다.
- 모달의 상태(
컴포지션 패턴 적용
모달 내부에서 컨텐츠를 유연하게 전달하기 위해서 컴포지션 패턴을 사용했다. props drilling 없이
children
을 통해 원하는 내용을 주입할 수 있도록 했다 .모달 내부 구조
Modal
Modal.Header
Modal.Body
Modal.Footer
Context API를 활용한 상태 관리
- 모달 내부의 자식 컴포넌트가 깊은 경우,
onClose
함수를 전달하려면 여러 단계의 props drilling이 발생하게 된다. Context API를 사용해서Provider
를 추가하고, 하위 컴포넌트가 모달 상태에 직접 접근할 수 있도록 했다.
- 모달 내부의 자식 컴포넌트가 깊은 경우,
이벤트 핸들링 : ESC키와 모달 배경 클릭 감지
- 모달 배경 클릭하거나 ESC 키를 눌렀을 때 모달창이 닫히도록
useKeyDown
훅을 구현했다.
- 모달 배경 클릭하거나 ESC 키를 눌렀을 때 모달창이 닫히도록
const useKeyDown = (key: string, onClose: () => void): void => { useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === key) onClose(); }; document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("keydown", handleKeyDown); }; }, [key, onClose]); };
기본적인 모달을 구현했지만, 모달은 트리거 영역과 컨텐츠 영역으로 나눠져서 더 고려해야 할 부분이 많다는 걸 알게 되었다. 추가적으로 고려해야 할 부분을 살펴보자.
추가적으로 더 고려해야 하는 부분
모달 컨텐츠에 대한
maxHeight
적용- 모달 컨텐츠가 긴 경우, 모달 자체가 페이지를 벗어날 수 있기 때문에 모달창 내부에서 스크롤이 가능하도록
maxHeight
속성을 적용해야 한다.
- 모달 컨텐츠가 긴 경우, 모달 자체가 페이지를 벗어날 수 있기 때문에 모달창 내부에서 스크롤이 가능하도록
키보드 인터렉션 및 포커스 관리
tab
키 클릭 시 포커스가 모달 내부에서만 순환하도록 처리해야 한다.모달이 열릴 때, 모달을 열었던 요소에 대한 참조를 저장해 둬서 모달이 닫힐 때, 참조된 요소로 포커스가 복원되어야 한다.
접근성 참고 링크
애니메이션 및 트랜지션 적용
모달은 조건부 렌더링(
open
상태에 따라 mount/unmount) 되기 때문에 부드러운 전환 효과가 필요하다.배경(dimmed)과 콘텐츠의 트랜지션을 별도로 적용하려면 요소를 분리하여 렌더링해야 한다.
모달의
open
상태와 싱크를 맞춘 별도의 상태 관리가 필요할 수도 있다.
중첩 모달 관리
여러 개의 모달이 열릴 경우, ESC 키 입력 시 최상위 모달만 닫혀야 한다.
하위 모달을 닫을 경우, 상위 모달까지 모두 닫혀야 한다.
마무리하며
모달은 단순한 UI 요소가 아니라, 접근성, 상태 관리, 애니메이션 등 다양한 고려 사항이 필요한 컴포넌트다. 추가로 고려해야 하는 부분을 알게 되었으니, 간단히 구현한 모달에 하나씩 적용해보려 한다.
참고 문서
Subscribe to my newsletter
Read articles from yarnmi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
