번역 자료 / / 2025. 5. 27. 11:37

[react 번역] createPortal API

원문: https://react.dev/reference/react-dom/createPortal


createPortal

createPortal은 일부 자식(children)을 DOM의 다른 위치에 렌더링할 수 있게 해줍니다.

<div>
  <SomeComponent />
  {createPortal(children, domNode, key?)}
</div>
  • 레퍼런스
    • createPortal(children, domNode, key?)
  • 사용법
    • DOM의 다른 위치에 렌더링하기
    • 포털로 모달 다이얼로그 렌더링하기
    • React 컴포넌트를 비-React 서버 마크업에 렌더링하기
    • React 컴포넌트를 비-React DOM 노드에 렌더링하기

레퍼런스

createPortal(children, domNode, key?)

포털을 만들려면 createPortal을 호출하고, 렌더링할 JSX와 렌더링할 DOM 노드를 전달하세요:

import { createPortal } from 'react-dom';

// ...

<div>
  <p>This child is placed in the parent div.</p>
  {createPortal(
    <p>This child is placed in the document body.</p>,
    document.body
  )}
</div>

아래 예시를 참고하세요.

포털은 DOM 노드의 물리적 위치만 변경합니다. 그 외의 모든 면에서, 포털로 렌더링된 JSX는 포털을 렌더링한 React 컴포넌트의 자식 노드로 동작합니다. 예를 들어, 자식은 부모 트리에서 제공된 context에 접근할 수 있고, 이벤트도 React 트리 기준으로 버블링됩니다.

파라미터

  • children: React로 렌더링할 수 있는 모든 것(JSX, <div />, <SomeComponent />, Fragment, 문자열, 숫자, 배열 등)
  • domNode: document.getElementById() 등으로 얻은 DOM 노드. 반드시 이미 존재하는 노드여야 합니다. 업데이트 시 다른 DOM 노드를 전달하면 포털 내용이 재생성됩니다.
  • optional key: 포털의 key로 사용할 고유 문자열 또는 숫자(선택).

반환값

createPortal은 JSX에 포함하거나 컴포넌트에서 반환할 수 있는 React 노드를 반환합니다. React가 이를 렌더링하면, 전달한 children을 지정한 domNode에 배치합니다.

주의사항

  • 포털에서 발생한 이벤트는 DOM 트리가 아니라 React 트리 기준으로 버블링됩니다. 예를 들어, 포털 내부에서 클릭하면, 포털을 감싸는 <div onClick>의 핸들러가 실행됩니다. 이로 인해 문제가 발생한다면, 포털 내부에서 이벤트 전파를 중단하거나, 포털 자체를 React 트리 상위로 옮기세요.

사용법

DOM의 다른 위치에 렌더링하기

포털(portal)은 컴포넌트의 일부 자식을 DOM의 다른 위치에 렌더링할 수 있게 해줍니다. 이를 통해 컴포넌트의 일부가 컨테이너를 "탈출"하여 페이지의 다른 곳에 표시될 수 있습니다. 예를 들어, 모달 다이얼로그나 툴팁을 페이지의 나머지 위에 띄울 때 유용합니다.

import { createPortal } from 'react-dom';

function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}

React는 전달한 JSX의 DOM 노드를 지정한 DOM 노드에 배치합니다.

포털이 없으면 두 번째 <p>는 부모 <div> 내부에 위치하지만, 포털을 사용하면 해당 요소가 document.body로 "텔레포트"됩니다.

<body>
  <div id="root">
    ...
      <div style="border: 2px solid black">
        <p>This child is placed inside the parent div.</p>
      </div>
    ...
  </div>
  <p>This child is placed in the document body.</p>
</body>

포털은 DOM 노드의 위치만 바꿀 뿐, context나 이벤트 버블링 등은 여전히 React 트리 기준으로 동작합니다.


포털로 모달 다이얼로그 렌더링하기

포털을 사용하면, 페이지의 나머지 위에 떠 있는 모달 다이얼로그를 만들 수 있습니다. 예를 들어, 부모 컨테이너에 overflow: hidden 등 스타일이 적용되어 있어도, 포털로 렌더링된 모달은 영향을 받지 않습니다.

접근성을 위해 포털을 사용할 때는 키보드 포커스 관리 등도 신경써야 합니다. WAI-ARIA Modal Authoring Practices를 참고하세요. 커뮤니티 패키지를 사용할 경우에도 접근성 가이드라인을 준수하는지 확인하세요.


React 컴포넌트를 비-React 서버 마크업에 렌더링하기

포털은 React 루트가 정적/서버 렌더링된 페이지의 일부일 때도 유용합니다. 예를 들어, Rails 등 서버 프레임워크로 빌드된 페이지에서, React로 만든 인터랙티브 영역을 사이드바 등 정적 영역에 삽입할 수 있습니다. 여러 개의 React 루트를 사용하는 것보다, 포털을 사용하면 하나의 React 트리로 상태를 공유할 수 있습니다.

import { createPortal } from 'react-dom';

const sidebarContentEl = document.getElementById('sidebar-content');

export default function App() {
  return (
    <>
      <MainContent />
      {createPortal(
        <SidebarContent />, 
        sidebarContentEl
      )}
    </>
  );
}

function MainContent() {
  return <p>This part is rendered by React</p>;
}

function SidebarContent() {
  return <p>This part is also rendered by React!</p>;
}

React 컴포넌트를 비-React DOM 노드에 렌더링하기

포털을 사용하면 React 외부에서 관리되는 DOM 노드의 내용을 제어할 수도 있습니다. 예를 들어, 비-React 지도 위젯의 팝업에 React 콘텐츠를 렌더링하려면 다음과 같이 할 수 있습니다.

const [popupContainer, setPopupContainer] = useState(null);

useEffect(() => {
  if (mapRef.current === null) {
    const map = createMapWidget(containerRef.current);
    mapRef.current = map;
    const popupDiv = addPopupToMapWidget(map);
    setPopupContainer(popupDiv);
  }
}, []);

return (
  <div style={{ width: 250, height: 250 }} ref={containerRef}>
    {popupContainer !== null && createPortal(
      <p>Hello from React!</p>,
      popupContainer
    )}
  </div>
);

출처: https://react.dev/reference/react-dom/createPortal

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유