Portal

Portal

Portal 컴포넌트는 자식 요소를 Portal 자신의 DOM 계층 밖에 존재하는 DOM 노드에 렌더링할 수 있게 해줘요.

출처: 문서

본문

소개 (Introduction)

Portal은 React의 createPortal() API를 바탕으로 만들어진 유틸리티 컴포넌트예요. createPortal()의 기능을 컴포넌트 형태로 편리하게 제공해주죠. Modal과 Popper 컴포넌트 내부에서도 사용돼요.

:::info React 문서에 따르면, 포털은 "자식 요소가 시각적으로 자신의 컨테이너를 '벗어나야(break out)' 할 때" 유용해요. 예를 들어 문서의 일반적인 흐름 밖에 존재해야 하는 모달이나 툴팁 같은 경우가 그렇죠. :::

일반적으로 컴포넌트의 자식은 그 컴포넌트의 DOM 트리 안에 렌더링돼요. 하지만 때로는 자식을 DOM의 다른 위치에 마운트해야 할 필요가 있어요. Portal 컴포넌트는 자식이 마운트될 DOM 노드에 ref를 전달하는 container prop을 받아요.

아래 데모는 Portal 안에 중첩된 <span>이 Portal의 DOM 계층 밖의 노드에 추가되는 방법을 보여줘요 — Mount children을 클릭해서 동작을 확인해보세요:

import * as React from 'react';
import Portal from '@mui/material/Portal';
import { Box } from '@mui/system';

export default function SimplePortal() {
  const [show, setShow] = React.useState(false);
  const container = React.useRef(null);

  const handleClick = () => {
    setShow(!show);
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        {show ? 'Unmount children' : 'Mount children'}
      </button>
      <Box sx={{ p: 1, my: 1, border: '1px solid' }}>
        It looks like I will render here.
        {show ? (
          <Portal container={() => container.current!}>
            <span>But I actually render here!</span>
          </Portal>
        ) : null}
      </Box>
      <Box sx={{ p: 1, my: 1, border: '1px solid' }} ref={container} />
    </div>
  );
}

기본 (Basics)

임포트 (Import)

import Portal from '@mui/material/Portal';

커스터마이즈 (Customization)

서버 사이드 Portal (Server-side Portals)

서버에는 DOM API가 없기 때문에 container prop 콜백을 사용해야 해요. 이 콜백은 React 레이아웃 이펙트 동안 호출돼요:

<Portal container={() => document.getElementById('filter-panel')!}>
  <Child />
</Portal>

:::error Portal 컴포넌트는 자식 요소를 서버에서 렌더링하는 데 사용할 수 없어요 — 클라이언트 사이드 하이드레이션(hydration)이 필요해요. React가 서버에서 createPortal() API를 지원하지 않기 때문이에요. 자세한 내용은 이 GitHub 이슈를 참고하세요. :::

Portal API

데모 (Demos)

이 React 컴포넌트의 사용 예시와 세부 사항은 컴포넌트 데모 페이지를 방문해보세요:

임포트 (Import)

import Portal from '@mui/material/Portal';
// or
import { Portal } from '@mui/material';

Props

Name Type Default Required Description
children node - No
container HTML element | func - No
disablePortal bool false No

Note: The ref is forwarded to the root element.

소스 코드 (Source code)

이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트의 구현을 살펴보는 것을 고려해보세요.

더 알아보기 (Learn more)