[NextJS] Portal 로 Modal을 띄어보자!

eunniverse·2024년 7월 21일

글쓰게된 계기

요새 nextjs와 typescript, tailwind CSS 를 사용해서 뭘 하나 만들어보고 있다. 와중에 modal 을 띄워야하는 일이 생겼는데, nextjs를 처음 사용해본 입장으로 굉장히 헤맸던 입장으로서 혹시나 도움이 될까하며 작성하는 글이다 ㅎㅎ

React의 Portal

VueJS에 Bootstrap을 얹어서 썼던 어연 3년, NextJS에서 Modal을 구현할 때도 기존에 썼던 방식처럼 쓰면 되는줄 알았다;; 하지만 Modal 이 최상단에 배치가 되지 않고, 다른 요소들의 position에 영향을 주는 문제가 발생했다.

위와 같은 문제를 해결하기 위해 사용한다는 React의 Portal, 무엇일까??

Portal 알아보기

portal을 이용하면 DOM을 사전에 선택하여 컴포넌트의 렌더링 위치를 설정할 수 있다. 즉, DOM의 계층구조 시스템에 종속되지 않으면서 컴포넌트를 렌더링 할 수 있다.

어디에 사용되는가?

주로 Modal이나 Tooltip과 같이 자식 컴포넌트지만, 최상단에 위치해야할 경우 사용한다.

어떻게 사용하는가?

body에 Portal 컴포넌트가 새롭게 생성할 모달 컴포넌트의 자리를 id로 잡아놓고 Portal 컴포넌트에서 document.getElementById 함수로 그 자리에 모달 컴포넌트를 렌더링한다.

구현 방법

  1. 우선 page.tsx에 modal-root를 만든다.
...
return (
    <main className="flex min-h-screen flex-col items-center justify-between bg-white">
      <HeadLoading/>
      <Header/>
      <Introduce/>
      <div id="modal-root"></div>
    </main>
  )
  1. Modal 컴포넌트에서는 modal-root에 모달 컴포넌트를 렌더링 시킨다.
...
 const modalContent:React.JSX.Element = (
        // modal html
 )

 // show 가 false 일 경우, 모달 안보여주도록
 if(!props.show) {
    return null;

 } else {
     // modal 을 만드는 요소 createPortal
     return ReactDOM.createPortal(
        modalContent,
        // @ts-ignore
        document.getElementById("modal-root")
     );
 }
  1. modal 을 사용하는 곳에서 컴포넌트를 선언해준다.
...
   <EmailModal show={show} onClose={closeModal} onShow={openModal}/>
profile
능력이 없는 것을 두려워 말고, 끈기 없는 것을 두려워하라

0개의 댓글