[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)
  • 태그

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

티스토리툴바