[React] Portal 컴포넌트 만들기

sumi-0011·2023년 6월 22일
0

📓 코드 저장소

목록 보기
3/4
post-thumbnail

Portal는 뭐야?

Portal이라고 이름이 정해있는 것은 아니지만,
저는 Portal이라는 이름을 사용하도록 하겠습니다.

지금부터 createPortal를 이용하여
보통의 컴포넌트 DOM 계층에서는 접근 할 수 없는
<body> 태그의 자식으로 컴포넌트를 렌더링 할 수 있는 Portal 컴포넌트를 구현하려고 합니다.

createPortal

React에서는 기본적으로 createPortal이라는 API를 제공합니다.

createPortal을 사용하면 일부 자식을 DOM의 다른 부분으로 렌더링 할 수 있습니다.

사용 예시

<div>
  <SomeComponent />
  {createPortal(children, domNode, key?)}
</div>

참고 링크 : createPortal

Portal 컴포넌트 만들기

리액트 공식 문서를 참고하여
createPortal를 이용해 body에 자식 노드를 렌더링 하는 Portal 컴포넌트를 만들어 보았습니다.

Portal.tsx

import { type PropsWithChildren, useState } from 'react';
import { createPortal } from 'react-dom';


// react.createPortal을 이용해 document.body에 children을 렌더링합니다
const Portal = ({ children }: PropsWithChildren) => {
  const [container, setContainer] = useState<Element | null>(null);

  useEffect(() => {
    if (document) {
      setContainer(document.body);
    }
  }, []);

  if (!container) return null;

  return createPortal(children, container);
};

export default Portal;
  • document.body같은 경우 mounted 시점 이후 부터 참조가 가능합니다.
  • 따라서, mounted가 되면 container 상태에 body 참조값을 저장하도록 하여 body에 렌더링할 수 있습니다.

    useState가 아닌 useRef 상태를 관리 한다면 container가 바뀌어도 화면이 렌더링 되지 않아 문제가 발생할 수 있음

참고 링크 : Rendering a modal dialog with a portal

사용 방법

Portal 컴포넌트의 자식 노드를 넘기면
자식 노드는 body에 렌더링되게 됩니다.

return ( 
  <Portal>{/*children*/}</Portal>
)
profile
안녕하세요 😚

0개의 댓글