ArcGIS JSAPI 팝업용 React Portal

너희들은 이상한 짓을 해



꽤 이상한 질문을 받습니다. 괜찮아, 꽤 이상한 대답이 있어. 발생하는 질문 중 하나는 사람들이 ArcGIS API for JavaScript에서 자신의 팝업으로 이상한 일을 할 수 있는 방법입니다.

팝업을 여러 개 가질 수 있나요? 아니.
Popup을 드래그할 수 있습니까? 아니.
팝업 크기를 조정할 수 있습니까? 아니.

이 모든 것에는 약간의 미묘함이 필요한 좀 더 미묘한 답변이 있지만 기본적으로는... 아니요.

가끔 나오는 질문 중 하나는 Popup에서 React 구성 요소를 사용할 수 있습니까?입니다. 물론 넌 할 수있어!

사실 React에는 이러한 종류의 사용 사례를 위한 API가 있습니다. React Portals . React Portals의 목적은 상위 DOM 외부에 존재하는 DOM 요소를 관리하는 것입니다. 가장 일반적인 사용 사례는 모달 대화 상자입니다. 또는 토스트 알림이나 페이지의 툴팁 및 팝오버일 수도 있습니다. 팝업에서도 이것을 활용할 수 있습니다!

당신의 마음에 포탈을 엽니다



Note: You can find the source code this project on github.



가장 먼저 하고 싶은 일은 일부 데이터를 가져와 내 Popup에 표시할 수 있는 React 구성 요소를 만드는 것입니다.

/// src/PopupInfo.js 
import React from 'react-dom';

const PopupInfo = ({ data }) => (
    <div className='popup-container'>
    <div className='my-popup'>
      <h1>{data.title}</h1>
      <p>
          {data.description}
      </p>
    </div>
  </div>
);

export default PopupInfo;


이것은 상당히 간단한 구성 요소입니다. 그러나 구성 요소를 원하는 만큼 복잡하게 만들 수 있습니다. 차트, 그래프, 애니메이션, 어쩌면 다른 맵?!?! 자신을 노크, 그것은 당신의 구성 요소입니다.

그런 다음 Popup 콘텐츠에 대한 래퍼 포털 구성 요소를 만들어야 합니다.

// src/PopupPortal.js 
import { useEffect } from "react";
import { createPortal } from "react-dom";

const PopupPortal = ({ mountNode, children }) => {
  const el = document.createElement("div");

  useEffect(() => {
    mountNode.appendChild(el);
    return () => mountNode.removeChild(el);
  }, [el, mountNode]);

  return createPortal(children, el);
};

export default PopupPortal;


이 구성 요소는 mountNode DOM 요소와 하위 구성 요소를 가져온 다음 React Portal에서 렌더링합니다. 그다지 복잡하지는 않지만 작업을 수행합니다. 나는 이것을 더 단순화 할 수 있다고 생각합니다.

// src/PopupPortal.js Option 2
import { createPortal } from "react-dom";

const PopupPortal = ({ mountNode, children }) => {
  return createPortal(children, mountNode);
};

export default PopupPortal;


여기서 내 유일한 관심사는 내가 원하지 않을 때 mountNode가 파괴될 수 있다는 것입니다. 내가 지나치게 조심스러울 수도 있지만 그게 내가 굴러가는 방식이다.

코코넛에 라임을 넣고



다음은 PopupPortal 를 사용하는 방법에 대한 간략한 미리보기입니다.

// src/App.js
import React, { useRef, useEffect, useState } from "react";

import PopupInfo from "./PopupInfo";
import PopupPortal from "./PopupPortal";

const popupRoot = document.createElement('div');

function App() {
  const mapDiv = useRef(null);
  const [ popupData, setPopupData ] = useState({});

  useEffect(() => {
    if (mapDiv.current) {
      ...
      sceneView.when(() => {
        ...
        function setContentInfo(center) {
          setPopupData({
            title: "My Popup with React Portal",
            description: `This is my React Portal: center = ${JSON.stringify(center.toJSON())}`,
          });
          return popupRoot;
        }
      });
    }
  }, [mapDiv]);

  return (
    <div className="mapDiv" ref={mapDiv}>
        <PopupPortal mount={popupRoot}>
            <PopupInfo data={popupData}></PopupInfo>
        </PopupPortal>
    </div>
  );
}

export default App;


좋아, 이것을 조금 분해하자. PopupTemplatecontent은 Popup 내용에 사용되는 HTML 요소를 반환하는 메서드를 포함하여 다양한 것일 수 있습니다. setContentInfo와 같은 메서드를 사용하여 구성 요소 상태를 업데이트하고 생성한 HTML 요소를 반환할 수 있습니다.

function setContentInfo(center) {
    setPopupData({
        title: "My Popup with React Portal",
        description: `This is my React Portal: center = ${JSON.stringify(center.toJSON())}`,
    });
    return popupRoot;
}


구성 요소의 컨텍스트에 존재하는 이 요소를 전달할 수 있으므로 Portal 구성 요소에 전달할 수 있습니다.

<div className="mapDiv" ref={mapDiv}>
    <PopupPortal mount={popupRoot}>
        <PopupInfo data={popupData}></PopupInfo>
    </PopupPortal>
</div>


이제 지도에서 Popup을 열면 Popup React 구성 요소로 채워집니다!

요약



ArcGIS API for JavaScript는 팝업에 대한 많은 기능을 제공합니다. 표, 차트, 미디어, 첨부 파일, 아케이드, 다양한 표현, 사용자 정의 작업 및 목록이 계속됩니다. 다양한 애플리케이션에서 가장 널리 사용되는 위젯이라는 점을 고려하면 지도에서 클릭하는 위치뿐만 아니라 지도에서 클릭하는 항목을 기반으로 콘텐츠를 완전히 제어할 수 있다는 사실은 정말 멋집니다. 재미있게 즐기세요. React Portals가 여러분이 작업해 온 특정 사용 사례를 해결한다는 것을 알 수 있습니다. 예를 들어, 이를 수행하는 비 포털 방법은 React.unmountComponentAtNode(container) 을 사용하는 것과 관련이 있습니다. 이는 훌륭하게 작동하지만 여러 React DOM을 관리하는 자체 문제를 제기합니다. 자세한 내용은 아래 영상에서 확인하실 수 있습니다!

좋은 웹페이지 즐겨찾기