React-Leaflet · ⚛️ React components for 🍃 Leaflet maps
React-Leaflet は Leaflet を React 上で使いやすくするラッパーライブラリです。 Vue2Leaflet との主な機能面の違いとして React の ref 機能との接続があります。Leaflet 内部の機能を React 的に呼び出せて便利です(自分の技術不足も少なからずありますが以前 Vue2Leaflet を使った時は生 JavaScript が混在したつくりになってしまいました)。
簡単に使ってみたデモが次です。地図上をクリックすると、クリックした地点の緯度経度情報を持ったマーカーが立ち、マーカーのポップアップが自動で開かれる、というコードです。
コードの主部分は次です。これだけでまあまあいい感じに地図を元に緯度経度をユーザにクリックで指定させられます。
import React from "react";
import { Map, Marker, Popup, TileLayer } from "react-leaflet";
/**
* クリックをマーカーにするマップ
*/
export default React.memo(function ClickToMarkerMap(props) {
// props から初期値を取得
const [markerLatLng, setMarkerLatLng] = React.useState(
props.markerLatLngDefault || null
);
// mapをclick時、クリックした地点にマーカーの緯度経度を更新
const onClickMap = (e) => setMarkerLatLng(e.latlng);
return (
<div>
{/* MapのClickイベントを定義、その他 props(center, zoom など) をそのままパス */}
<Map onClick={onClickMap} {...props}>
{/* 適当な無料地図を開く他候補としては地理院地図とか */}
<TileLayer url="https://{s}.tile.osm.org/{z}/{x}/{y}.png" />
{markerLatLng && (
<Marker
position={markerLatLng}
// ref を介することで react-leaflet の開発者に負担をかけず(この例に関しては children と popup の bind を接続してもらっているけれども)、 leaflet のコードを呼び出し
// @see https://leafletjs.com/reference-1.6.0.html#popup
ref={(ref) => ref && ref.leafletElement.openPopup()}
>
<Popup position={markerLatLng}>
{/* ポップアップでクリックされた地点の緯度経度を表示 */}
<pre>{JSON.stringify(markerLatLng, null, 2)}</pre>
</Popup>
</Marker>
)}
</Map>
</div>
);
});
React というか JSX 記法の利点としてスプレッド演算子で props を渡していくことによって容易に Chain of Responsibility(処理できるコードに当たるまで色々たらい回しにしていくデザインパターン) でを実現できる、という点があります。スプレッド演算子による props リレーは他コンポーネントの props 定義が変わってもスプレッド演算子を使っている部分に影響が起きにくいという利点もあります(名前被りで事故る場合が考えられます)。これと ref を使うことで Leaflet をラップしたコンポーネントをさらにラップした……と機能を損なわず連鎖したコンポーネントを作れます。
マンガでわかる Chain of Responsibility – Qiita