メインコンテンツまでスキップ

「react」タグの記事が2件件あります

全てのタグを見る

· 約3分
ogumaru

概要

有効/無効の 2 つの状態を持つ要素を利用して、createContextで作成した状態を保持・切り替えさせたい。

Calcite Design System のCalciteSwitchを利用し、状態をクリックで変更しようとしたが、実際はクリックをしても見た目が有効なまま変わらなかった。

意図した動作としては、選択状態に応じて下の表のようになる。

スイッチの状態表示
有効青、右
無効白、左

環境

項目バージョン
@esri/calcite-components-react0.32.0
react18.2.0

原因・対策

onClickでイベントの処理をしつつchecked={context.isSetAttr}のようにcheckedプロパティで状態管理をすると適切に表示されなくなる。

checked=truecheckedであれば当然青になるが、checked=falseであっても表示が上の表の「有効」のものになる。

ドキュメントにはcheckedtrue, falseを持つとあるが、実際にはfalseだと意図した通りの表示にならない。

下記コードでは状態に関わらず「有効」のものが表示される。

(contextは上位コンポーネントより渡しており、isSetAttrboolean)

<CalciteSwitch
checked={context.isSetAttr}
onClick={(e) => {
const input = e.target as HTMLInputElement;
context.setIsSetAttr(input.checked);
}}
/>

正しくは下記のようにonCalciteSwitchChangeでイベントの処理をしつつ、checkedに状態を持たせない。

<CalciteSwitch
onCalciteSwitchChange={(e) => {
const input = e.target;
context.setIsSetAttr(input.checked);
}}
/>

Fires when the checked value has changed. Note: The event payload is deprecated, use the component's checked property instead.

Switch | Calcite Design System | ArcGIS Developers - (developers.arcgis.com)

これで意図した表示にはなるが、コンポーネント自体に状態を保持しておらず、複数箇所からの操作がある場合に若干不安がある。

· 約4分
ogumaru

概要

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>
</>
);
};

環境

項目内容
React18.2.0
ArcGIS API for JavaScript4.24.7
TypeScript4.8.4
webpack5.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 | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)

一方、MapViewがインスタンス化された場合、containerプロパティはDOMContainer.containerを指してしまい、指定できるのはHTMLDivElementのみとなる。

DOMContainer | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)

そのため下記コードでは型エラーが発生してしまう。

const mapView = new MapView(...);
mapView.container = "viewDiv"

Type 'string' is not assignable to type 'HTMLDivElement'.ts(2322)

MapViewではなく、これが継承している__esri.Accessorsetメソッドを持っており、これを利用することで動的にcontainerを指定することができた。

Accessor | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)