ReactJS - 포털: React 애플리케이션에서 새로운 차원으로의 관문
안녕하세요, React 개발자 지망생 여러분! 오늘 우리는 React 포털의 세상으로 흥미로운 여정을 떠납니다. 당신이 집 (React 애플리케이션)을 짓고 있는 중에 갑자기 주요 복도를 거치지 않고 하나의 방에서 다른 방으로 무언가를 운반할 필요가 있다는 것을 깨닫는다면, 그것이 바로 React 포털이 컴포넌트에 대해 하는 일입니다!
React 포털이란?
React 포털은 부모 컴포넌트의 DOM 계층 구조 외부에 존재하는 DOM 노드로 자식을 렌더링하는 첫 번째 클래스 방법을 제공합니다. 간단히 말하면, 자식 컴포넌트를 DOM 트리의 다른 곳에 렌더링할 수 있게 해주는 웜홀을 만드는 것입니다. 하지만 여전히 React 컴포넌트 계층 구조의 일부입니다.
왜 포털이 필요한가요?
"제 컴포넌트를 원하는 대로 어디에나 렌더링할 수 없나요?"라고 궁금할 수 있습니다. 대부분의 경우에는 그렇습니다! 하지만 포털이 유용한 상황이 있습니다:
- 모달 다이얼로그
- 툴팁 3.漂浮 메뉴
- 컨테이너를 벗어나야 하는 위젯
포털의 작동 방식과 사용법에 대해 더 깊이 알아보겠습니다.
첫 번째 포털 만들기
포털을 만들기 위해 ReactDOM.createPortal()
메서드를 사용합니다. 기본 예제를 보겠습니다:
import React from 'react';
import ReactDOM from 'react-dom';
function MyPortalComponent() {
return ReactDOM.createPortal(
<h1>어딘가 다른 곳에 렌더링됩니다!</h1>,
document.getElementById('portal-root')
);
}
이 예제에서 우리는 'portal-root' ID를 가진 DOM 노드로 <h1>
엘리먼트를 렌더링하는 포털을 만들고 있습니다. 이 노드는 주요 React 애플리케이션의 루트 엘리먼트 외부에 존재해야 합니다.
ReactDOM.createPortal()
메서드를 분해해 보겠습니다:
- 첫 번째 인수는 렌더링할 React 엘리먼트입니다.
- 두 번째 인수는 렌더링할 DOM 엘리먼트입니다.
실 세계 예제: 모달 다이얼로그
더 실질적인 예제를 만들어 보겠습니다 - 애플리케이션 콘텐츠 위에 나타나는 모달 다이얼로그입니다.
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay">
<div className="modal-content">
{children}
<button onClick={onClose}>닫기</button>
</div>
</div>,
document.getElementById('modal-root')
);
}
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<h1>반갑습니다! My App</h1>
<button onClick={() => setIsModalOpen(true)}>모달 열기</button>
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h2>이것은 모달입니다</h2>
<p>주요 React 트리 외부에서 렌더링됩니다!</p>
</Modal>
</div>
);
}
이 예제에서 우리는 포털을 사용하여 콘텐츠를 렌더링하는 재사용 가능한 Modal
컴포넌트를 만들었습니다. App
컴포넌트는 모달의 가시성을 제어합니다.
다음과 같은 일이 일어납니다:
-
Modal
컴포넌트는isOpen
프로퍼티를 확인합니다. - 열려 있으면, 포털을 사용하여 'modal-root' 엘리먼트로 콘텐츠를 렌더링합니다.
- 모달 콘텐츠에는 닫기 버튼이 포함되어 있으며, 이 버튼을 클릭하면
onClose
프로퍼티가 호출됩니다. -
App
컴포넌트는 상태를 사용하여 모달의 가시성을 제어합니다.
이벤트 버블링을 통한 포털
포털의 흥미로운 측면 중 하나는 DOM 트리 어디에나 콘텐츠를 렌더링할 수 있지만, 이벤트는 예상대로 React 트리를 거슬러 올라간다는 것입니다. 예제를 보겠습니다:
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Parent() {
const [clicks, setClicks] = useState(0);
const handleClick = () => {
setClicks(clicks + 1);
};
return (
<div onClick={handleClick}>
<h1>클릭 횟수: {clicks}</h1>
<Portal>
<Child />
</Portal>
</div>
);
}
function Portal({ children }) {
return ReactDOM.createPortal(
children,
document.getElementById('portal-root')
);
}
function Child() {
return <button>나를 클릭해!</button>;
}
이 예제에서 포털 내의 버튼을 클릭하면 부모 컴포넌트의 클릭 핸들러가 호출되어 클릭 횟수가 증가합니다. 이 행동은 예상된 이벤트 전파를 유지하는 데 매우 유용합니다.
최선의 관행과 고려사항
포털을 사용할 때 다음 포인트를 염두에 두세요:
- 접근성: 포털 콘텐츠가 접근성이 있도록 보장하세요, 특히 스크린 리더기에 대한 접근성.
- 이벤트 처리: 이벤트는 React 트리를 거슬러 올라가지 않고 DOM 트리를 거슬러 올라갑니다.
- 스타일링: 포털 콘텐츠는 별도의 스타일 고려가 필요할 수 있습니다.
- 정리: 컴포넌트가 언마운트될 때 포털을 정리하세요.
포털 메서드
React 포털과 관련된 주요 메서드를 표로 정리하겠습니다:
메서드 | 설명 |
---|---|
ReactDOM.createPortal(child, container) |
포털을 만듭니다. child 는 어떤 렌더링 가능한 React 자식이고, container 는 DOM 엘리먼트입니다. |
ReactDOM.unmountComponentAtNode(container) |
DOM에서 마운트된 React 컴포넌트를 제거하고 이벤트 핸들러와 상태를 정리합니다. |
결론
React 포털은 렌더링 시 기본 컴포넌트 계층 구조를 벗어나는 강력한 기능입니다. 모달 다이얼로그, 툴팁, 그리고 다른 UI 요소를 만들 때 특히 유용합니다.
Responsibility comes with great power! 포털을 지혜롭게 사용하고, 애플리케이션의 구조와 접근성에 미치는 영향을 항상 고려하세요.
행복한 코딩을 하고, 여러분의 포털이 항상 흥미로운 새로운 차원으로 이끄시길 바랍니다!
Credits: Image by storyset