🦨
ReactのWebアプリでマップ表示と住所検索
はじめに
実装した画面はこんな感じです。
テキストボックスに住所を入力して ”search” を押すと該当する場所のマップが表示されます。
コンポーネントの最終的なコードはこちら。
React, Google Maps API を使ってマップ表示をする際、以下のライブラリを使った方法をよく見かけます。
- google-map-react
- react-google-maps
これらを使って実装すると Error や Warning が発生してしまいました。
Google Maps API のアップデートに追いついてないのが原因のようです。
そこで、今回は上記のライブラリを使わない方法で実装をやってみました。
事前準備
以下の作業は完了済みの前提です。
- Google Cloud にてプロジェクト作成
- APIとサービスの画面から以下のAPIを有効化
- Maps JavaScript API
- Geocoding API
- 認証情報の画面から API Key をコピー
手順
Reactプロジェクト作成。
npm create vite@latest
マップ表示のために、Google Maps JavaScript API を利用します。
API script の Loader が用意されているの、そちらをインストールして使います。
npm install @googlemaps/js-api-loader && npm i -D @types/google.maps
package.json の中身はこんな感じです。
.env ファイルを作成して API Key を貼り付けます。
VITE_MAPS_API_KEY="**********"
公開したくないので、.gitignore に .env を追記しておきます。
まずは、コンポーネントを作成してマップを表示してみます。
import { useEffect, useRef } from "react";
import { Loader } from "@googlemaps/js-api-loader";
export const MyMap = () => {
const position = { lat: 35.710063, lng: 139.8107 };
const mapRef = useRef<HTMLDivElement>(null);
// API Key を使ってローダーを初期化
const loader = new Loader({
apiKey: import.meta.env.VITE_MAPS_API_KEY,
version: "weekly",
});
// 初回レンダリング時に使用するライブラリを非同期でロード
useEffect(() => {
(async () => {
const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
loader.importLibrary("maps"),
loader.importLibrary("marker"),
]);
// 地図の描画
const map = new Map(mapRef.current!, {
center: position,
zoom: 10,
mapId: "DEMO_MAP_ID",
});
// マーカーの描画
new AdvancedMarkerElement({ map, position, title: "" });
})();
}, []);
return (
<>
<div ref={mapRef} style={{ height: "400px", width: "400px" }}></div>
</>
);
};
ブラウザで見るとこんな感じです。
次に、ジオコーディング API を使って入力された住所の検索をやってみます。
上記のコードに少し変更を加えます。
// ステート化
const [position, setPosition] = useState({ lat: 35.710063, lng: 139.8107 });
// ステートの変更検知
useEffect(() => {
・・・
}, [position]);
// フォームハンドラーを追加
async function submit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const address = String(formData.get("address"));
const { Geocoder } = await loader.importLibrary("geocoding");
const geocoder = new Geocoder();
geocoder.geocode({ address }, (results, status) => {
if (results) {
const { lat, lng } = results[0].geometry.location;
if (status === "OK") {
setPosition({ lat: lat(), lng: lng() });
}
}
});
}
// フォームを追加
return (
<>
・・・
<form onSubmit={submit} className="mt-4">
<input type="text" name="address" />
<button>search</button>
</form>
</>
);
ブラウザで見るとこんな感じになります。
参考
Reactプロジェクト作成
Google Maps JavaScript API Loader
Maps JavaScript API
マーカーの配置
ジオコーディング
Discussion