Posts Creasteportal
Post
Cancel

Creasteportal

https://react-ko.dev/reference/react-dom/createPortal

1
2
3
4
<div>  
	<SomeComponent />  
	{createPortal(children, domNode, key?)}  
</div>

parameters

  • children : JSX or 문자열 or 숫자 등 리액트로 렌더링 할 수 있는 모든 것
  • domNode : document.getElementById()가 반환하는 것과 같은 일부 DOM 노드
  • key (optional) : 포털의 키로 사용할 고유 문자열 또는 숫자

Caveats

  • 포털의 이벤트는 DOM 트리가 아닌 React 트리에따라 전파된다
  • 포털은 DOM 노드의 물리적 배치만 변경한다. 다른 모든 면에서는 JSX는 이를 렌더링하는 React 컴포넌트의 자식 노드 역할을 한다.

Usage

Rendering React components into non-React server markup

리액트 루트가 리액트로 빌드되지 않은 정적페이지 또는 서버렌더링 페이지의 일부일 때 유용할 수 있다. 여러 개 개별 React 루트를 사용하는 것보다 포털을 사용하여 앱의 일부가 DOM의 다른 부분에 렌더링 되더라도 앱을 공유 state를 가진 단일 React 트리로 처리할 수 있다.

Rendering React components into non-React DOM nodes

포털을 사용해 React 외부에서 관리되는 DOM 노드의 콘텐츠를 관리할 수도 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { useRef, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { createMapWidget, addPopupToMapWidget } from './map-widget.js';

export default function Map() {
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const [popupContainer, setPopupContainer] = useState(null);

  useEffect(() => {
    if (mapRef.current === null) {
      const map = createMapWidget(containerRef.current);
      mapRef.current = map;
      const popupDiv = addPopupToMapWidget(map);
      setPopupContainer(popupDiv);
    }
  }, []);

  return (
    <div style= ref={containerRef}>
      {popupContainer !== null && createPortal(
        <p>Hello from React!</p>,
        popupContainer
      )}
    </div>
  );
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import 'leaflet/dist/leaflet.css';
import * as L from 'leaflet';

export function createMapWidget(containerDomNode) {
  const map = L.map(containerDomNode);
  map.setView([0, 0], 0);
  L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '© OpenStreetMap'
  }).addTo(map);
  return map;
}

export function addPopupToMapWidget(map) {
  const popupDiv = document.createElement('div');
  L.popup()
    .setLatLng([0, 0])
    .setContent(popupDiv)
    .openOn(map);
  return popupDiv;
}

  • 리액트 외부에 있는 div의 내용을 리액트를 사용하여 채워넣을 수 있음
This post is licensed under CC BY 4.0 by the author.