概要
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
を指定することができた。