序章

Googleマップは、さまざまな構成設定をサポートするGoogleが提供する地図サービスです。 Googleマップをアプリケーションに追加すると、住所や座標のセットよりも多くのコンテキスト情報をユーザーに提供できます。

このチュートリアルは、Google Maps APIをReactコンポーネントに統合し、Webサイトに地図を表示できるようにすることを目的としています。

前提条件

このチュートリアルを完了するには、次のものが必要です。

注: Google Maps APIを使用するときに「開発目的のみ」のメッセージを回避するには、有効なクレジットカードを提供し、それをGoogleCloudProjectの請求先アカウントに関連付ける必要があります。このチュートリアルには必要ありません。

このチュートリアルは、Nodev14.2.0で検証されました。 npm v6.14.5、 react v16.13.1、および google-maps-react v.2.0.6。

ステップ1—Reactアプリケーションのセットアップ

このチュートリアルでは、create-react-appを使用して新しいReactアプリのスキャフォールディングを行います。

ファーストラン npx 使用する create-react-app ターミナルウィンドウ:

  1. npx create-react-app react-googlemaps

次に、新しいプロジェクトディレクトリに移動します。

cd react-googlemaps

コードを追加する前に、次のコマンドを使用して依存関係をインストールしましょう。

  1. npm install google-maps-react@2.0.6

注:オプションで、この時点で不要なファイルを削除して、 src ディレクトリ。 あなたは必要ありません logo.svg, App.css, index.css. 削除した場合 index.css、も削除する必要があります import 為に index.cssindex.html ビルドエラーを回避するため。

この時点で、Reactアプリケーションがあります。 google-maps-react 図書館。 これで、アプリケーションでマップを使用して探索できます。

ステップ2—使用 MapGoogleApiWrapper

次に、編集する必要があります App.js ファイルを作成し、コードをGoogleマップをロードするコンポーネントに置き換えます。

開ける App.js:

  1. nano src/App.js

の内容を置き換えます App.js 次のコード行を使用します。

src / App.js
import React, { Component } from 'react';
import { Map, GoogleApiWrapper } from 'google-maps-react';

const mapStyles = {
  width: '100%',
  height: '100%'
};

export class MapContainer extends Component {
  render() {
    return (
      <Map
        google={this.props.google}
        zoom={14}
        style={mapStyles}
        initialCenter={
          {
            lat: -1.2884,
            lng: 36.8233
          }
        }
      />
    );
  }
}

export default GoogleApiWrapper({
  apiKey: 'YOUR_GOOGLE_MAPS_API_KEY_GOES_HERE'
})(MapContainer);

注:置換 YOUR_GOOGLE_MAPS_API_KEY_GOES_HERE Google MapsJavasScriptAPIキーを使用します。

警告: APIキーは、意図しない目的で他のユーザーが使用できるため、パブリックリポジトリ(GitHubなど)にコミットするファイルには保存しないでください。

基本的なGoogleマップの機能については、これが必要なすべてのコードです。

The Map コンポーネントはいくつかのオプションの小道具を取り入れます:

  • style -CSSスタイルオブジェクト
  • zoom -マップの中心に焦点を合わせていることを表す数値
  • initialCenter -緯度と経度の座標を含むオブジェクト

この例では、次を定義しています。

  • CSSスタイルオブジェクト 100% 幅と 100% 身長
  • のズーム値 14
  • との場所 -1.2884, 36.8233 (ケニア、ナイロビのケニヤッタ国際コンベンションセンター)

ターミナルを開き、アプリを実行します。

  1. npm start

そして、マップがブラウザにロードされることを確認します。

The GoogleApiWrapperHigher-OrderComponent(HOC)であり、GoogleAPIのラッパーを提供します。 または、 GoogleApiWrapper HOCは、ラップされたコンポーネントの小道具で呼び出される関数を渡すことで構成でき、次のように構成オブジェクトを返す必要があります。

export default GoogleApiWrapper(
  (props) => ({
    apiKey: props.apiKey
  }
))(MapContainer)

この時点で、ReactアプリケーションにGoogleマップがあります。 これで、Googleマップの他の機能の実装を検討できます。

ステップ3—使用 MarkersInfoWindow

ここで、MarkerInfoWindowをコードに追加します。

まず、インポートする必要があります MarkerInfoWindow からのコンポーネント google-maps-react 2つのロードを実現するためのライブラリ。

src / App.js
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';

以前のコンポーネントはステートレスでしたか? 状態管理のために状態を追加する必要があります。

src / App.js
// ...

export class MapContainer extends Component {
  state = {
    showingInfoWindow: false,  // Hides or shows the InfoWindow
    activeMarker: {},          // Shows the active marker upon click
    selectedPlace: {}          // Shows the InfoWindow to the selected place upon a marker
  };

  // ...
}

次に、次の場合のイベントハンドラーを追加する必要があります。 Map そしてその Marker クリックされます。

src / App.js
// ...

export class MapContainer extends Component {
  // ...

  onMarkerClick = (props, marker, e) =>
    this.setState({
      selectedPlace: props,
      activeMarker: marker,
      showingInfoWindow: true
    });

  onClose = props => {
    if (this.state.showingInfoWindow) {
      this.setState({
        showingInfoWindow: false,
        activeMarker: null
      });
    }
  };

  // ...
}

The onMarkerClick メソッドは、を表示するために使用されます InfoWindow、のコンポーネントです google-maps-react クリックされた詳細を表示するポップアップウィンドウの機能を提供するライブラリ Marker.

The onClose メソッドは閉じるためのものです InfoWindow ユーザーが上の閉じるボタンをクリックすると InfoWindow.

追加してコンポーネントを完成させましょう <Marker><InfoWindow> コンポーネントに render 方法:

src / App.js
// ...

export class MapContainer extends Component {
  // ...

  render() {
    return (
      <Map
        google={this.props.google}
        zoom={14}
        style={mapStyles}
        initialCenter={
          {
            lat: -1.2884,
            lng: 36.8233
          }
        }
      >
        <Marker
          onClick={this.onMarkerClick}
          name={'Kenyatta International Convention Centre'}
        />
        <InfoWindow
          marker={this.state.activeMarker}
          visible={this.state.showingInfoWindow}
          onClose={this.onClose}
        >
          <div>
            <h4>{this.state.selectedPlace.name}</h4>
          </div>
        </InfoWindow>
      </Map>
    );
  }
}

アプリを実行します。

  1. npm start

そして、あなたが1つを持っていることを確認してください Marker とともに InfoWindow クリックすると:

フォローアップの練習として、あなたは行ってさらにいくつかを追加することができます <Marker>s <Map> そしてあなたへのより多くの双方向性 <InfoWindow>.

ステップ4—ユーザーの現在地を表示する

次に、ブラウザの現在の場所を取得するようにマップを設定します。 Navigator を使用します。これは、読み取り専用のプロパティであり、 Geolocation デバイスの場所へのWebコンテンツアクセスを提供するオブジェクト。

あなたの中で src ディレクトリは新しいファイルを作成し、それに名前を付けます Map.js:

  1. nano src/Map.js

次の名前のコンポーネントを作成します CurrentLocation —ここで、ブラウザの場所を取得するためのすべての機能を構築します。

src / Map.js
import React from 'react';
import ReactDOM from 'react-dom';

const mapStyles = {
  map: {
    position: 'absolute',
    width: '100%',
    height: '100%'
  }
};

export class CurrentLocation extends React.Component {
  // ...
}

export default CurrentLocation;

あなたはあなたのにいくつかのデフォルトの小道具を追加することから始めます <CurrentLocation> コンポーネント、マップを設定する必要があるため、 center 現在の場所が提供されていない場合。 これはブールプロップによって処理されます centerAroundCurrentLocation:

src / Map.js
// ...

CurrentLocation.defaultProps = {
  zoom: 14,
  initialCenter: {
    lat: -1.2884,
    lng: 36.8233
  },
  centerAroundCurrentLocation: false,
  visible: true
};

次に、コンポーネントをステートフルにする必要があります。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  constructor(props) {
    super(props);

    const { lat, lng } = this.props.initialCenter;

    this.state = {
      currentLocation: {
        lat: lat,
        lng: lng
      }
    };
  }
}

// ...

また、あなたを更新しましょう <CurrentLocation> ネットワークの問題や予期しないメンテナンスのためにGoogleMapsAPIが利用できないシナリオを処理するためのコンポーネント。 また、ブラウザの現在の場所が提供され、その場所にマップを再配置する状況も処理します。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  componentDidUpdate(prevProps, prevState) {
    if (prevProps.google !== this.props.google) {
      this.loadMap();
    }
    if (prevState.currentLocation !== this.state.currentLocation) {
      this.recenterMap();
    }
  }
}

// ...

を定義しましょう recenterMap() ときに呼び出される関数 currentLocation コンポーネントの状態が更新されます。 それは使用します panTo() マップの中心を変更する方法。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  recenterMap() {
    const map = this.map;
    const current = this.state.currentLocation;
    const google = this.props.google;
    const maps = google.maps;

    if (map) {
      let center = new maps.LatLng(current.lat, current.lng);
      map.panTo(center);
    }
  }
}

// ...

次に、マップがすでにロードされているときにシナリオを処理する必要があります。 これはによって処理されます componentDidMount() 現在の場所をフェッチするためのコールバックを設定するライフサイクルメソッド。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  componentDidMount() {
    if (this.props.centerAroundCurrentLocation) {
      if (navigator && navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(pos => {
          const coords = pos.coords;
          this.setState({
            currentLocation: {
              lat: coords.latitude,
              lng: coords.longitude
            }
          });
        });
      }
    }
    this.loadMap();
  }
}

// ...

に注意してください loadMap() 関数? 先に進んでそれを定義しましょう。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  loadMap() {
    if (this.props && this.props.google) {
      // checks if google is available
      const { google } = this.props;
      const maps = google.maps;

      const mapRef = this.refs.map;

      // reference to the actual DOM element
      const node = ReactDOM.findDOMNode(mapRef);

      let { zoom } = this.props;
      const { lat, lng } = this.state.currentLocation;
      const center = new maps.LatLng(lat, lng);

      const mapConfig = Object.assign(
        {},
        {
          center: center,
          zoom: zoom
        }
      );

      // maps.Map() is constructor that instantiates the map
      this.map = new maps.Map(node, mapConfig);
    }
  }
}

// ...

The loadMap() 関数は、コンポーネントがレンダリングされた後に呼び出され、マップを配置する場所へのDOMコンポーネントへの参照を取得します。

君の <CurrentLocation> コンポーネントはほぼ完成しています。 しかし、あなたはあなたの前の <Marker> 現在の場所(つまり、ブラウザの現在の場所)を選択するため、親子コンポーネント通信を介して導入する必要があります。 renderChildren() 子コンポーネントのメソッドの呼び出しを担当するメソッド。

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  renderChildren() {
    const { children } = this.props;

    if (!children) return;

    return React.Children.map(children, c => {
      if (!c) return;

      return React.cloneElement(c, {
        map: this.map,
        google: this.props.google,
        mapCenter: this.state.currentLocation
      });
    });
  }
}

// ...

そして最後に、 render() 方法:

src / Map.js
// ...

export class CurrentLocation extends React.Component {
  // ...

  render() {
    const style = Object.assign({}, mapStyles.map);

    return (
      <div>
        <div style={style} ref="map">
          Loading map...
        </div>
        {this.renderChildren()}
      </div>
    );
  }
}

// ...

最後に、更新する必要があります MapContainer のコンポーネント App.js:

  1. nano src/App.js

交換してください Map 新しいコンポーネント CurrentLocation 成分:

src / App.js
import React, { Component } from 'react';
import { GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';

import CurrentLocation from './Map';

export class MapContainer extends Component {
  state = {
    showingInfoWindow: false,
    activeMarker: {},
    selectedPlace: {}
  };

  onMarkerClick = (props, marker, e) =>
    this.setState({
      selectedPlace: props,
      activeMarker: marker,
      showingInfoWindow: true
    });

  onClose = props => {
    if (this.state.showingInfoWindow) {
      this.setState({
        showingInfoWindow: false,
        activeMarker: null
      });
    }
  };

  render() {
    return (
      <CurrentLocation
        centerAroundCurrentLocation
        google={this.props.google}
      >
        <Marker onClick={this.onMarkerClick} name={'Current Location'} />
        <InfoWindow
          marker={this.state.activeMarker}
          visible={this.state.showingInfoWindow}
          onClose={this.onClose}
        >
          <div>
            <h4>{this.state.selectedPlace.name}</h4>
          </div>
        </InfoWindow>
      </CurrentLocation>
    );
  }
}

export default GoogleApiWrapper({
  apiKey: 'YOUR_GOOGLE_MAPS_API_KEY_GOES_HERE'
})(MapContainer);

アプリを実行します。

npm start

ブラウザに向かって、最初にマップをロードする必要があります initialCenter 次に、リロードしてブラウザの現在の場所を選択します。 Marker この場所に配置され、voilà、これで完了です。

結論

この記事では、 <Map> コンポーネントを反応させ、追加します Marker、および関連付けます InfoWindow それに。 また、地図に現在地を表示させました。

この知識に基づいて、ポリラインやポリゴンを作成したり、マップにイベントリスナーを追加したりするなど、より高度な機能を実装できます。

Reactの詳細については、 React.js シリーズのコーディング方法をご覧になるか、Reactトピックページで演習やプログラミングプロジェクトを確認してください。