ReactJS - 포털: React 애플리케이션에서 새로운 차원으로의 관문

안녕하세요, React 개발자 지망생 여러분! 오늘 우리는 React 포털의 세상으로 흥미로운 여정을 떠납니다. 당신이 집 (React 애플리케이션)을 짓고 있는 중에 갑자기 주요 복도를 거치지 않고 하나의 방에서 다른 방으로 무언가를 운반할 필요가 있다는 것을 깨닫는다면, 그것이 바로 React 포털이 컴포넌트에 대해 하는 일입니다!

ReactJS - Portals

React 포털이란?

React 포털은 부모 컴포넌트의 DOM 계층 구조 외부에 존재하는 DOM 노드로 자식을 렌더링하는 첫 번째 클래스 방법을 제공합니다. 간단히 말하면, 자식 컴포넌트를 DOM 트리의 다른 곳에 렌더링할 수 있게 해주는 웜홀을 만드는 것입니다. 하지만 여전히 React 컴포넌트 계층 구조의 일부입니다.

왜 포털이 필요한가요?

"제 컴포넌트를 원하는 대로 어디에나 렌더링할 수 없나요?"라고 궁금할 수 있습니다. 대부분의 경우에는 그렇습니다! 하지만 포털이 유용한 상황이 있습니다:

  1. 모달 다이얼로그
  2. 툴팁 3.漂浮 메뉴
  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() 메서드를 분해해 보겠습니다:

  1. 첫 번째 인수는 렌더링할 React 엘리먼트입니다.
  2. 두 번째 인수는 렌더링할 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 컴포넌트는 모달의 가시성을 제어합니다.

다음과 같은 일이 일어납니다:

  1. Modal 컴포넌트는 isOpen 프로퍼티를 확인합니다.
  2. 열려 있으면, 포털을 사용하여 'modal-root' 엘리먼트로 콘텐츠를 렌더링합니다.
  3. 모달 콘텐츠에는 닫기 버튼이 포함되어 있으며, 이 버튼을 클릭하면 onClose 프로퍼티가 호출됩니다.
  4. 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>;
}

이 예제에서 포털 내의 버튼을 클릭하면 부모 컴포넌트의 클릭 핸들러가 호출되어 클릭 횟수가 증가합니다. 이 행동은 예상된 이벤트 전파를 유지하는 데 매우 유용합니다.

최선의 관행과 고려사항

포털을 사용할 때 다음 포인트를 염두에 두세요:

  1. 접근성: 포털 콘텐츠가 접근성이 있도록 보장하세요, 특히 스크린 리더기에 대한 접근성.
  2. 이벤트 처리: 이벤트는 React 트리를 거슬러 올라가지 않고 DOM 트리를 거슬러 올라갑니다.
  3. 스타일링: 포털 콘텐츠는 별도의 스타일 고려가 필요할 수 있습니다.
  4. 정리: 컴포넌트가 언마운트될 때 포털을 정리하세요.

포털 메서드

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