React Portal을 사용하면 모달을 만들때 좋다는 것을 듣기는 했었지만 이제서야 알아보게 된다..
Portal
Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM노드로 자식을 렌더링 하는 최고의 방법을 제공해준다.
ReactDOM.createPortal(child, container)
사용법은 이렇다.
첫 번째 인자(child)는 엘리먼트, 문자열, 혹은 fragment와 같은 어떤 종류이든 렌더링할 수 있는 React 자식입니다.
두 번째 인자(container)는 DOM엘리먼트 이다.
사용한 모습을 보고 가자면 일반적인 모달 컴포넌트 사용하는 것 처럼
<Modal isOpen={isModalOpen} onClose={closeModal} />
이런식으로 필요한 prop을 내려주고
function Modal({ isOpen, onClose }) {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className={style.modal}>
<div className={style.modalContent}>
<span className={style.closeButton} onClick={onClose}>
×
</span>
<p>Modal Content</p>
</div>
</div>,
document.getElementById("modal")
);
}
이렇게 받아서 사용을 하게 된다.
장점과 단점
장점
1. DOM 구조의 유연성:
• createPortal을 사용하면 컴포넌트를 루트 DOM 트리의 다른 부분에 렌더링할 수 있습니다. 이를 통해 모달, 툴팁, 드롭다운 등 특정 UI 요소를 기존의 DOM 구조와 분리하여 쉽게 관리할 수 있습니다.
2. 스타일 및 레이아웃 문제 해결:
• 포털을 사용하면 스타일링 및 레이아웃 문제를 해결할 수 있습니다. 예를 들어, 부모 요소의 overflow: hidden 속성으로 인해 발생하는 스크롤 문제를 피할 수 있습니다.
3. Z-Index 이슈 해결:
• 포털을 통해 최상위 DOM 노드에 렌더링할 경우, z-index 문제를 효과적으로 관리할 수 있습니다. 모달이나 툴팁이 다른 요소 위에 항상 제대로 표시되도록 보장할 수 있습니다.
4. 전역 이벤트 처리:
• 포털을 사용하면 전역 이벤트 리스너를 쉽게 추가할 수 있습니다. 예를 들어, 모달을 클릭하여 닫는 기능을 구현할 때 유용합니다.
단점
1. 컴포넌트 트리 외부와의 상호작용 복잡성:
• 포털은 컴포넌트 트리 외부에 렌더링되기 때문에, 부모와 자식 컴포넌트 간의 이벤트 전달 및 상태 관리가 복잡해질 수 있습니다. React의 전파 메커니즘을 벗어나게 되므로 신경 써야 할 부분이 많아집니다.
2. 접근성 이슈:
• 포털을 사용할 때는 접근성(A11Y)을 고려해야 합니다. 특히 모달의 경우, 스크린 리더가 포커스를 제대로 인식할 수 있도록 추가적인 조치를 취해야 합니다.
3. 테스트 복잡성 증가:
• 포털을 사용하는 컴포넌트는 테스트하기가 더 어려울 수 있습니다. 테스트 환경에서 포털을 렌더링하고, 상호작용을 시뮬레이션하는 작업이 추가적인 설정을 요구할 수 있습니다.
4. 초기 학습 곡선:
• 포털의 개념과 사용법을 이해하는 데 시간이 걸릴 수 있습니다. 특히 React 초보자에게는 다소 복잡하게 느껴질 수 있습니다.
마지막으로 까먹으면 안되는게 하나 있다.
위에 보여준 코드에서
return ReactDOM.createPortal(
<div className={style.modal}>
<div className={style.modalContent}>
<span className={style.closeButton} onClick={onClose}>
×
</span>
<p>Modal Content</p>
</div>
</div>,
document.getElementById("modal")
);
부분의 document.getElementById를 사용하기 위해 index.html의 기존 root 옆에
<div id="modal_back"></div>
<div id="modal"></div>
<div id="root"></div>
이렇게 추가를 해줘야 한다.
이름은 정해진 것은 없고 원하는 이름으로 지어주고 그 이름으로 지정해 주면 된다.
'이것저것' 카테고리의 다른 글
| Framer Motion과 Intersection Observer (0) | 2024.06.22 |
|---|---|
| PWA (1) | 2024.06.13 |
| pm2 알아보기 (0) | 2024.05.22 |
| padStart와 padEnd (JS) (0) | 2024.05.18 |
| Nominatim API (0) | 2024.05.09 |