React.js 포털

자체 DOM 트리 외부에서 요소를 렌더링하는 마법

React.js의 순간 이동

React는 앱 내부의 완전히 다른 위치에 자식을 탑재할 수 있는 "Portal"이라는 특별하고 매우 강력한 구성 요소를 제공한다는 사실을 알고 계셨습니까? 그렇지 않다면 새로운 것을 배울 때입니다!

React.js 포털의 구조

다음은 이전에 React.js의 Portal 구성 요소가 작동하는 방식에 대한 간략한 개요입니다.

  • 코드의 어딘가에서 Portal의 자식을 호스팅할 요소를 마운트합니다.
  • 그런 다음이 요소에 대한 참조를 얻습니다.
  • 그런 다음 앱의 다른 위치에서 Portal 구성 요소를 마운트하고 호스트 요소에서 얻은 참조를 전달합니다.
  • 이제 Portal 내부에 마운트된 모든 것은 실제로 첫 번째 단계부터 호스트에 마운트됩니다.

진행 상황을 더 잘 이해하기 위해 포털 기능을 설명하기 위해 다음과 같은 간단한 시각화를 만들었습니다.

Image ee9c2dac28e7

Image 70ff8978589d

Image 886ed0a34985

이러한 이미지를 기반으로 하는 다음 그래픽은 동일한 프로세스를 보여주지만 이번에는 코드 예제가 단순화되었습니다.

Image dd655b015a22

Image ab94e9940e3a

Portal은 처음에 생각하는 것보다 훨씬 강력합니다. 여러 Portal의 여러 자식을 동일한 대상 요소로 렌더링할 수도 있습니다. 포털의 마운트 순서는 호스트에 있는 요소의 순서도 정의합니다.

Image de39ae9a02a2

Image b12fdf680f24

텔레포트된 모든 자식을 포함할 host-element에 대한 참조를 공유하는 것도 매우 쉽습니다. 공식 문서에는 document.getElementById의 사용법이 설명되어 있지만 React.js의 useRef-hook을 사용할 수도 있습니다. 다음 코드 예제는 지금까지 설명한 모든 것을 보여주는 간단한 구현을 보여줍니다.

import React, { useEffect, useRef, useState } from "react";
import ReactDOM, { createPortal } from "react-dom";

//
// Link to sandbox:
// 👉 https://codesandbox.io/s/react-16-8-0-forked-d8lm1?file=/src/index.js:0-1067
//

// A simple demonstration of the React-Portal
// w/ multiple portals for the same target.
function App() {
  const ref = useRef(null);
  const [isRefReady, setIsRefReady] = useState(false);

  // Run one more render to actually
  // show the content of our portal.
  // This is necessary, as the setter
  // for the 'ref' alone won't trigger
  // a render.
  useEffect(() => {
    setIsRefReady(Boolean(ref));
  }, []);

  return (
    <div>
      <div>
        {/* The 'target' aka host for our portals. */}
        <header ref={ref} style={{display: "flex", gap: 8 }} />
        <hr/>
      </div>
      <h1>
        Debug
      </h1>
      {isRefReady && createPortal(<button>one</button>, ref.current)}
      {isRefReady && createPortal(<button>two</button>, ref.current)}
      <div>
        {isRefReady && createPortal(<button>three</button>, ref.current)}
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector("#root"));

Portal 구성 요소가 코딩을 단순화하는 방법

React.js 포털의 가장 일반적인 사용 사례는 아마도 Modal 구성 요소의 구현일 것입니다. 앱 트리 루트에서 대상을 정의하고 Portal 구성 요소를 사용하여 모든 콘텐츠 위에 안정적으로 떠 있는 모달을 모든 곳에서 탑재할 수 있습니다.

실제로 구현한 또 다른 사용 사례는 탭 컨테이너의 사용입니다. 탭 컨테이너에는 탭 항목 자체와 탭이 선택될 때 렌더링할 콘텐츠가 모두 필요하므로 탭 행과 선택한 콘텐츠에 대해 하나씩 두 개의 호스트를 정의하기만 하면 됩니다.

그런 다음 탭 항목과 선택한 콘텐츠에 대한 포털을 각각 사용하는 구성 요소 배열을 마운트합니다. 이를 통해 비즈니스 로직이 실제로 속한 위치, 즉 각각의 개별 구성 요소에 배치할 수 있습니다.

Image 2761da74cf8c

Image e7810bb469d2

Portal 구성 요소에 대한 훨씬 더 흥미로운 사용 사례가 분명히 있습니다. 이것이 가능하다고 생각하는 가장 큰 장점은 단일 구성 요소에서 비즈니스 로직의 긴밀한 결합이며, 이 구성 요소의 자식은 다른 위치에 탑재됩니다. 이 패턴은 뛰어난 유연성과 사용자 정의를 허용하지만 뷰가 실제로 어떻게 관련되어 있는지 코드베이스에서 혼란을 초래할 수 있습니다.

또한 React.js 포털에 대한 모든 세부 정보는 공식 문서를 참조하십시오.