인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

oridori2705님의 프로필 이미지
oridori2705

작성한 질문수

[React / VanillaJS] UI 요소 직접 만들기 Part 2

팝오버 (2/3) createPortal 활용

popover createPortal 방식에서

해결된 질문

작성

·

26

0

portal할 요소를 아래처럼 작성하고 있는데

<div id="popoverRoot" />  

저는 이거를 popover를 사용하는 개발자가 신경안쓸 수 있도록
하는 방법이 있지않을까 해서 두 가지 방법을 생각했는데

하나는 useLayoutEffect 내부에서 아래와 같은 로직으로 div요소를 만드는 방법하고,

  useLayoutEffect(() => {
    if (typeof window !== 'undefined') {
      const portalElement = document.getElementById(portalId)
      if (!portalElement) {
        const newPortalElement = document.createElement('div')
        newPortalElement.id = portalId

        document.body.appendChild(newPortalElement)
      }
    }
  }, [])


아니면 document.body로 보내는 방법을 생각했는데

  return createPortal(
    ... 
     ,
    document.body
  )


두 방법 중 어느게 적절한지를 잘 모르겠어서..
혹은 위 방법처럼 했을 때 어떤 문제가 생기는지도 아직 예상이 안되는데 혹시 강사님의 생각은 어떠신지 궁금합니다!

 

 

답변 2

0

정재남님의 프로필 이미지
정재남
지식공유자

<div id="popoverRoot" />

강의에서는 페이지단위로 다른 내용을 소개하기 위해 어쩔 수 없이 페이지 내 컴포넌트별로 따로 넣어줬지만, 실제 서비스에서는 최상단 컴포넌트(_layout.tsx 또는 _app.tsx 등)에 딱 한 번만 넣으면 됩니다. 다른걸 생각하실 이유가 없을 것 같네요.

0

안녕하세요, 인프런 AI 인턴입니다.

oridori2705님께서 질문하신 포털 기법에 대한 두 가지 접근 방식에 대해 설명드리겠습니다.

첫 번째 방법은 useLayoutEffect를 사용하여 필요한 경우에만 DOM에 div 요소를 추가하는 방식입니다. 이 방식은 popover 루트 요소를 특정 portalId를 기준으로 관리할 수 있게 하여, 여러 모달이나 팝오버가 발생할 때 DOM 구조의 혼란을 줄일 수 있습니다. 그러나 DOM 조작을 수작업으로 관리해야 하므로, 요소의 생성 및 제거 시 추가적인 고려사항이 발생할 수 있습니다.

두 번째 방법은 createPortal 함수의 두 번째 인자로 document.body를 직접 사용하는 것입니다. 이 방식은 가장 간편하게 포털을 구현할 수 있는 방법 중 하나로, 재사용이 가능한 모달이나 팝오버 같은 요소를 쉽게 관리할 수 있습니다. 하지만 이 경우, 여러 개의 포털 요소가 있을 때 전역으로 관리되므로, 특정 상황에서 특정 포털을 타겟팅하거나 관리하는 것이 어려울 수 있습니다.

두 방식 모두 각각의 장단점이 있으며, 요구사항과 사용자의 개발 환경에 따라 선택이 달라질 수 있습니다.

  • 첫 번째 방법의 장점: 특정 ID로 관리되어 명확한 요소 타겟팅 가능.
  • 첫 번째 방법의 단점: 추가 코드가 필요하며, 직관적이지 않을 수 있음.
  • 두 번째 방법의 장점: 간결하며, 대부분의 경우에 바로 적용 가능.
  • 두 번째 방법의 단점: 특정 포털 요소를 구별하기 어렵고, 전역 관리로 인해 발생 가능한 충돌 관리 필요.

관련 질문으로 createPortal 활용해서 modal 만들 때 활용한 MutationObserver 코드 관련 질문와 비슷한 내용이 있으니 참고해 보시면 좋을 것 같습니다. 해당 질문에서는 createPortal을 활용하여 모달을 관리하는 방법에 대한 토론이 진행되고 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

oridori2705님의 프로필 이미지
oridori2705

작성한 질문수

질문하기