본문 바로가기

클라이언트/React
[리액트(React)] 포탈(Portal)

// 포탈, Portal

- 부모 컴포넌트의 DOM 요소들 바깥에 컴포넌트를 렌더링하고 싶을 때 사용한다.

- 모달, 팝업 등의 구현이 용이하다.

- 부모 컴포넌트의 바깥에 렌더링하기 때문에 부모 컴포넌트의 css 적용을 받지 않는다.


1. react-dom 에서 createPortal을 import 한다.

import {createPortal} from 'react-dom';


2. createPortal을 return 한다.

- 첫 번째 인수는 jsx 코드, 두 번째 인수는 해당 컴포넌트를 표시할 HTML 요소이다.

return createPortal(
  <>
  </>,
  document.getElementById('')  //다른 방법으로 받아도 됨
);

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Refs & Portals</title>
  </head>
  <body>
    <div id="modal"></div>
    <div id="content">
      <div id="root"></div>
    </div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

 

import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import { createPortal } from 'react-dom';

const ResultModal = forwardRef(function ResultModal(
  { targetTime, remainingTime, onReset },
  ref,
) {

  return createPortal(
    <dialog ref={dialog} className="result-modal" onClose={onReset}>
      {userLost && <h2>You lost</h2>}
      {!userLost && <h2>Your score: {score}</h2>}
      <p>
        The target time was <strong>{targetTime} seconds.</strong>
      </p>
      <p>
        You stopped the timer with{' '}
        <strong>{formattedRemainingTime} seconds left.</strong>
      </p>
      <form method="dialog" onSubmit={onReset}>
        <button>Close</button>
      </form>
    </dialog>,
    document.getElementById('modal'),
  );
});

export default ResultModal;