LoginSignup
12
13

More than 3 years have passed since last update.

ReactHooksでGoogleMapAPIを扱う

Posted at

何を作るか

googleMapAPIを使ってgooglemapっぽいのを作りましたので、そのまとめです。
React使いたいな〜って単純な理由でReactで作りましたが、差分更新が簡単にできたので嬉しかったです:open_hands:

ezgif.com-video-to-gif.gif

長くなってしまうので、とりあえず
- map表示
- 現在地表示
- 吹き出し表示
まで!

環境構築

create-react-appで作っていきます。

create-react-app map
cd map
yarn start

TSで作るなら

create-react-app map --typescript
cd map
yarn start

使用するライブラリはgoogle-map-reactです。
googlemapをReactで扱うにはいろんなライブラリがありますが、単純に参考記事の多さで選びました。
google-map-react 公式

yarn add -D google-map-react
// Typescript使うなら↓
yarn add -D @types/google-map-react

あとはAPIキーを取得しなきゃですが、そこは割愛…

Map表示

直接でも良いですがApp.jsはMapのレンダリングに使います。

App.js
import React, { Component } from "react";
import Maps from "./Maps";

class App extends Component {
  render() {
    return (
      <div>
        <Maps />
      </div>
    );
  }
}

export default App;
Maps.js
import React, { useState, useEffect } from "react";
import GoogleMapReact from "google-map-react";

//APIKEYは""としていれば開発者モードで使えます
const APIKEY = "";

const Maps = () => {
  const [center, setCenter] = useState({ lat: "", lng: "" });
  const [zoom, setZoom] = useState(13);

  return (
    //高さ指定してあげないとMap出ません!
    <div style={{ height: "100vh", width: "100%" }}>
    //google-map-reactからimport!
    //bootstrapURLKeys,center,zoom値があれば表示されます
      <GoogleMapReact
        bootstrapURLKeys={{ key: APIKEY }}
        center={center}
        defaultZoom={zoom}
      >
      </GoogleMapReact>
    </div>
  );
};

export default Maps;

現在地表示

カスタムマーカーを作るのはgoogle-map-reactを使えば簡単にできました!
GoogleMapReactに子コンポーネントとして書き込み、緯度経度を持たせてあげるだけです:eyes:

Maps.js
<GoogleMapReact
  bootstrapURLKeys={{ key: APIKEY }}
  center={center}
  defaultZoom={zoom}
 >  
    <Marker
     lat={XXXXXXXXX}
     lng={XXXXXXXXX}
    />       
</GoogleMapReact>

これをgeolocationを使って現在地に反映させます。

Maps.js

const Maps = () => {

 //centerなどの値もState管理に
  const [center, setCenter] = useState({ lat: "", lng: "" });
  const [zoom, setZoom] = useState(13);
  const [currentPosition, setCurrentPosition] = useState();

  // 初期表示地点
  const success = data => {
    const currentPosition = {
      lat: data.coords.latitude,
      lng: data.coords.longitude
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };

  //geolocation使えない場合の値を返す
  const error = data => {
    const currentPosition = {
      lat: 34.673542,
      lng: 135.433338
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };
 //初期読み込み時のみgeolocationを動かす
  useEffect(() => {
    navigator.geolocation.getCurrentPosition(success, error);
  }, []);

  return (
    <div style={{ height: "100vh", width: "100%" }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: APIKEY }}
        center={center}
        defaultZoom={zoom}
      >
        {currentPosition ? (
          <Marker
            lat={currentPosition.lat}
            lng={currentPosition.lng}
          />
        ) : null}
      </GoogleMapReact>
    </div>
  );
};

export default Maps;

吹き出し表示

Openかどうかをstate管理し、trueであれば表示します

Maps.js
const Maps = () => {

  const [isOpen, setIsOpen] = useState(false);
  const changeState = () => {
    setIsOpen(!isOpen);
  };

  return (
     :
        {isOpen ? (
          <Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
        ) : null}
      </GoogleMapReact>
    </div>
  );
};

export default Maps;

Maps.js

const Maps = () => {

  const [center, setCenter] = useState({ lat: "", lng: "" });
  const [zoom, setZoom] = useState(13);
  const [currentPosition, setCurrentPosition] = useState();
  const [isOpen, setIsOpen] = useState(false);

  // 初期表示地点
  const success = data => {
    const currentPosition = {
      lat: data.coords.latitude,
      lng: data.coords.longitude
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };

  const error = data => {
    const currentPosition = {
      lat: 34.673542,
      lng: 135.433338
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };
  useEffect(() => {
    navigator.geolocation.getCurrentPosition(success, error);
  }, []);

  const changeState = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div style={{ height: "100vh", width: "100%" }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: APIKEY }}
        center={center}
        defaultZoom={zoom}
      >
        {currentPosition ? (
          <Marker
            lat={currentPosition.lat}
            lng={currentPosition.lng}
            text="My Marker"
            color="blue"
            changeState={changeState}
          />
        ) : null}
        {isOpen ? (
          <Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
        ) : null}
      </GoogleMapReact>
    </div>
  );
};

export default Maps;

なので全体はこんな感じ↓

Maps.js
import React, { useState, useEffect } from "react";
import GoogleMapReact from "google-map-react";
import "../styles.css";
const APIKEY = "";

const Maps = () => {
  const [center, setCenter] = useState({ lat: 34.665442, lng: 135.432338 });
  const [zoom, setZoom] = useState(13);
  const [currentPosition, setCurrentPosition] = useState();
  const [isOpen, setIsOpen] = useState(false);

  // 初期表示地点
  const success = data => {
    const currentPosition = {
      lat: data.coords.latitude,
      lng: data.coords.longitude
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };

  const error = data => {
    const currentPosition = {
      lat: 34.673542,
      lng: 135.433338
    };
    setCurrentPosition(currentPosition);
    setCenter(currentPosition);
  };
  useEffect(() => {
    navigator.geolocation.getCurrentPosition(success, error);
  }, []);

  const changeState = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div style={{ height: "100vh", width: "100%" }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: APIKEY }}
        center={center}
        defaultZoom={zoom}
      >
        {currentPosition ? (
          <Marker
            lat={currentPosition.lat}
            lng={currentPosition.lng}
            text="My Marker"
            color="blue"
            changeState={changeState}
          />
        ) : null}
        {isOpen ? (
          <Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
        ) : null}
      </GoogleMapReact>
    </div>
  );
};

export default Maps;

Markerとかは切り分けて普通に作ればOKです!
↓こんな感じに
https://codesandbox.io/embed/google-maps-react-9slxw?fontsize=14&hidenavigation=1&theme=dark

とりあえず基本のところまで書いてみました。
詰まったところいっぱいあるのでかいつまんで残していきます:writing_hand:

参考記事

公式
https://github.com/google-map-react/google-map-react/blob/master/API.md#ondragend-map--void

基本表示まで
https://levelup.gitconnected.com/reactjs-google-maps-with-custom-marker-ece0c7d184c4

geolocationで現在地を初期表示に
https://medium.com/@allynak/how-to-use-google-map-api-in-react-app-edb59f64ac9d

高さ固定
https://github.com/tomchentw/react-google-maps/issues/323

googlemapAPIに関するヒントいろいろ
https://www.granfairs.com/blog/staff/google-maps-api-03

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13