React의 createPortal

이정수·2024년 9월 30일
0

ReactDeepDive

목록 보기
5/5

| createPortal 공식문서 바로가기

흥미를 끄는 리액트의 기능이 생겨 이를 알아보는 글입니다.
이름도 무려 포탈이다..!

포탈이란 무엇인고? 게임을 하다보면 캐릭터가 어떤 포탈 속에 쏙 빨려들어가서 이곳에서 저곳으로 이동하게 된다.

리액트 공식문서에서는 createPortal을 이렇게 설명한다.

부모 컴포넌트의 DOM 계층 구조의 외부에 있는 DOM노드로 자식 컴포넌트를 랜더링 할 수 있다.

createPortal(children, domNode, key?)

  • children : 포털로 보낼 것. React로 랜더링할 수 있는 모든것이 가능하다
    • ex) 컴포넌트, 숫자, 문자열, 배열 등..
    • Type : ReactNode
  • domNode : children을 보낼 장소, 포탈리 열리는 곳
    • Type: Element | DocumentFragment
    • 📍 createProtal 실행 시점에 이미 존재하고있는 노드여야 한다.
  • key ?: 포털 키 (고유한 문자열 또는 숫자)
    • 리액트가 렌더링 된 요소들을 효율적으로 추적하고 업데이트 할 수 있게 해주는 중요한 역할을 한다.

코드와 함께 보자
부모인 div 태그 안에 자식요소인 p태그와 createPortal로 생성한 어떤 자식노드가 있다.

<div>
  <p>This child A .부모div아래에 위치한다.</p>
  {createPortal(
    <p>This child B. 부모div아래의 위치에서 벗어나, document.body위에 있다.</p>,
    document.body
  )}
</div>

개발자 도구를 열어서 DOM구조를 확인해보면 아래 사진과 같다.
(위 코드는 블로그에 정리하기위해 p태그 내부 글만 정리한것이다..)

  • 포털은 DOM노드의 물리적 배치만 변경한다.
  • 그 외의 모든 면에서는 React 구조의 영향을 받는다.
    • 포털의 이벤트는 DOM트리가 아닌 리액트 트리에 따라 자식(child B)에서 부모(div)로 버블링된다.
    • = 이말은 root-div 안쪽에 존재하는 부모 요소에 이벤트 핸들러를 걸어두고 childB를 클릭해도 부모요소까지 이벤트가 전달된다..!(신기)

✅ 정리하자면!

포탈은 특정 요소를 실제 DOM요소에 랜더링 하면서도, react컴포넌트 트리에서는 자신의 자리에 남아 본연의 역할을 수행한다..

이것이 바로 위에서 말했던 '물리적 배치만 변경한다'라는 말의 의미이다.

예를들어

<APP>
	<Content>
    	<Modal /> //🗣️위로 올라가고 싶어요..
    </Content>
</APP>

<Modal/><Content>의 내부에 있지만, createPortal을 이용해 원하는 위치에 랜더링 시킬 수 있다. DOM의 위치상으로는 content의 품을 떠났지라고, react-tree상에서는 여전히 contents의 자식으로 남아있고 이벤트 버블링도 content로 전달된다.

즉, createPortal은 그저 렌더링 위치만 이동시켜준 것이다.

사용법 / 이걸 왜 쓸까..?

자식컴포넌트를 DOM상의 다른곳에 위치시키는것에 사용된다.

  • Modal, 툴팁, 드롭다운메뉴
  • React가 관리하지 않는 곳(라이브버리, 정적페이지)에서 React컴포넌트 렌더링 하기

단점

  • 남용시 잦은 리렌더링이 불필요한 DOM조작을 초래하여 성능 저하
  • 클라이언트 사이드에서만 작동해, 서버사이드 렌더링시 주의
    • 서버에서 만든 index.html, 클라이언트에서 만든 index.html가 달라서 초기화면이 달라지거나, 검색엔진 최적화에서 문제가 발생할 수 있다.
  • 동작 시 DOM 렌더링으로 인한 DOM 구조 예측이 어려움

cf) 모달을 만들 때, createPortal 말고도 dialog 태그를 사용하면 좀더 쉽게 만들 수 있다고 한다.

profile
keep on pushing

0개의 댓글