概要
ArcGIS API for JavaScript (@arcgis/core)で MapView を利用する際、インスタンス化時に container プロパティにセレクタの文字列かHTMLElementを指定することで、そこに地図を表示することができる。
React を利用する都合上、静的な HTML ではなく、表示対象となる要素(React コンポーネント)が描画されたあと、そこに表示されるようにしたい。
実装は ES Modules および TypeScript を利用して行った。
結論
useEffect内で__esri.Accessor.set()からcontainerを指定する。
import { useEffect } from "react";
import MapView from "@arcgis/core/views/MapView";
// ここでは container は指定しない。
// レイヤの操作をする都合上、
// export する必要があるためsetup内でインスタンス化できない。
export const mapView = new MapView({
/** 略 **/
});
const setup = () => {
// 動的に container を指定
mapView.set("container", "viewDiv");
};
export const App = () => {
useEffect(setup, []);
return (
<>
<div id="viewDiv"></div>
</>
);
};
環境
| 項目 | 内容 |
|---|---|
| React | 18.2.0 |
| ArcGIS API for JavaScript | 4.24.7 |
| TypeScript | 4.8.4 |
| webpack | 5.74.0 |
動的な配置
MapViewがインスタンス化されたときにcontainerに指定した際、この時点で該当の HTML 要素がない場合は地図が表示されない。
React を利用している場合、コンポーネントがマウントされたタイミングで描画されるように、useEffect内でMapViewをインスタンス化すれば問題なく表示ができる。
containerプロパティ
サンプルコードなどでは下記のようにコンストラクタでcontainerに HTML 要素のid文字列を指定することが多い。
const mapView = new MapView({
// (略)
container: "viewDiv",
});
このとき、containerプロパティの型は string | HTMLDivElementとなっているため、TypeScript の型エラーは出ない。
(ヒントには__esri.DOMContainerProperties.container?: string | HTMLDivElementとでるが、該当の型はドキュメントには見つからなかった)
一方、MapViewがインスタンス化された場合、containerプロパティはDOMContainer.containerを指してしまい、指定できるのはHTMLDivElementのみとなる。
そのため下記コードでは型エラーが発生してしまう。
const mapView = new MapView(...);
mapView.container = "viewDiv"
Type 'string' is not assignable to type 'HTMLDivElement'.ts(2322)
MapViewではなく、これが継承している__esri.Accessorがsetメソッドを持っており、これを利用することで動的にcontainerを指定することができた。
