[React - 기초] Portals

2022. 3. 17. 13:57·React/패스트캠퍼스
반응형

1. Portals? 

DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링 하는 최고의 방법이다. 

 

일반적으로 컴포넌트를 렌더링 메서드에서 엘리먼트를 반환할 때 부모 노드에서 가장 가까운 자식으로 DOM이 

마운트 된다. 

 

그런데 가끔 DOM의 다른 위치에서 자식을 삽입하는 것이 유용할 수 있다. 

예를 들어,  overflow: hidden이나 z-index가 있는 경우 시각적으로 자식을 "튀어나오도록" 보여야 하는 경우가 있다. 

다이얼로그, 툴팁 같은 것 말이다.

 

2. 필요성

import React, { useState } from "react";

export default function Portals(props) {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button
        style={{
          position: "absolute",
          left: 100,
        }}
        onClick={() => setIsOpen(true)}
      >
        open
      </button>

      {isOpen && (
        <div
          style={{
            position: "absolute",
            zIndex: 99,
            top: `50%`,
            left: `50%`,
            transform: "translate(-50%,-50%)",
            border: "1px solid black",
            padding: 24,
            backgroundColor: "white",
          }}
        >
          <p>{props.title}</p>
          <p>{props.description}</p>

          <button onClick={() => setIsOpen(false)}>OK</button>
        </div>
      )}

      {isOpen && (
        <div
          style={{
            position: `fixed`,
            backgroundColor: "grey",
            top: 0,
            left: 0,
            bottom: 0,
            right: 0,
          }}
        />
      )}
    </>
  );
}

간단하게 버튼을 누르면 화면이 모두 가려지고 다이얼로그가 나오는 컴포넌트를 만들었다. 

 

import React from "react";
import Portals from "./PortalDialog";

export default function Example() {
  return (
    <div>
      <Portals title={"Hello!"} description={"Portal Example"} />

      <div style={{ position: "absolute" }}>
        <button>하하하</button>
      </div>
    </div>
  );
}

부모 컴포넌트에서 다이알로그를 호출하고, 바로 아래에 " 하하하 " 버튼이 출력되게 작성하였다. 

 

이때, 다이알로그에서는 position: "absolute" 그리고 배경을 postion: "fixed"를 주어서 모두 가리는 작업을 했는데, 

부모 컴포넌트의 또다른 자식 컴포넌트인 " 하하하 " 버튼은 사라지지 않았다. 

 

 <div>
      <div style={{ position: "absolute" }}>
        <button>하하하</button>
      </div>

      <Portals title={"Hello!"} description={"Portal Example"} />
</div>

물론 Portals 태그와 button이 있는 div의 순서를 바꾼다면 " 하하하 " 버튼은 사라질 것이다. 

그렇지만, 작은 프로젝트에서는 가능할지라도 여러 가지 컴포넌트를 사용하는 경우 순서를 바꾸는 게 쉬운 일은 아니다.

 

정리하면, 모든 레이어가 순차적으로 가지고 있는 Stack을 벗어나는 일을 해야 할 경우에 Portal이 필요하다. 

 

3. 사용하기 

사용방법은 생각보다 간단하다. 

pubilc 폴더에 있는 index.html 파일의 root div 아래에 portal div를 한 개 추가해준다. 

 

import React from "react";
import { createPortal } from "react-dom";
import Portals from "./PortalDialog";

const Portal = (props) => {
  return createPortal(props.childre, document.getElementById("portal"));
};

export default function Example() {
  return (
    <div>
      <Portal>
        <Portals title={"Hello!"} description={"Portal Example"} />
      </Portal>

      <div style={{ position: "absolute" }}>
        <button>하하하</button>
      </div>
    </div>
  );
}

그리고 createPortal()을 사용해서 Portal 컴포넌트를 만들고 다이얼로그를 감싸주면 된다. 

 

이렇게 작업을 한다면 Portals 다이얼로그가 root div에 만들어지는 것이 아닌 portal div에 만들어지게 된다. 

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'React > 패스트캠퍼스' 카테고리의 다른 글

[React - 기초] PropTypes  (2) 2022.03.19
[React - 기초] Render Props  (1) 2022.03.18
[React - 기초] Memoization  (2) 2022.03.15
[React - 기초] Hooks  (0) 2022.03.10
[React - 기초] React와 리랜더링  (0) 2022.03.09
'React/패스트캠퍼스' 카테고리의 다른 글
  • [React - 기초] PropTypes
  • [React - 기초] Render Props
  • [React - 기초] Memoization
  • [React - 기초] Hooks
잉여개발자
잉여개발자
풀스택 개발자를 목표로 잉여롭게 개발 공부도 하면서 다양한 취미 생활도 즐기고 있는 잉여 개발자입니다.
  • 잉여개발자
    잉여로운 개발일지
    잉여개발자
    • 분류 전체보기 (789)
      • 개발정보 (36)
      • 개발환경 (7)
      • 개발생활 (19)
      • React (141)
        • 이론 (23)
        • 기능 (12)
        • 실험실 (88)
        • 버그 (6)
        • 패스트캠퍼스 (9)
        • Npm (3)
      • React Native (28)
        • 공통 (6)
        • TypeScript (3)
        • JavaScript (18)
        • 버그 (1)
      • Next.js (30)
        • 이론 (13)
        • 실험실 (13)
        • 버그 (3)
      • Web (35)
      • 알고리즘 (202)
        • 풀이 힌트 (39)
      • JavaScript (47)
      • TypeScript (29)
        • 기초 (27)
        • 실험실 (2)
      • Node.js (13)
        • 이론 (0)
        • 기능 (3)
        • 실험실 (9)
        • 버그 (1)
      • 도커 (4)
      • CCNA (22)
        • 이론 (4)
        • 문제 (18)
      • 취미생활 (167)
        • 잉여로운 칵테일 (2)
        • 잉여의 식물키우기 (130)
        • 잉여로운 여행기 (11)
        • 잉여의 제2외국어 (21)
        • 잉여로운 책장 (2)
      • Java (1)
        • Java의 정석 (1)
      • 꿀팁 공유 (3)
  • 태그

    바질
    식물
    redux
    영어독학
    다이소
    ReactNative
    타입스크립트
    ChatGPT
    영어회화
    네트워크
    네이버 부스트캠프
    타일러영어
    리얼클래스
    react
    리액트
    프로그래머스
    webpack
    Node.js
    Babel
    typescript
    알고리즘
    덤프
    CCNA
    바질 키우기
    Docker
    next.js
    CSS
    javascript
    자바스크립트
    리얼학습일기
  • hELLO· Designed By정상우.v4.10.1
잉여개발자
[React - 기초] Portals
상단으로

티스토리툴바