it-roy-ru.com

Использование Google Map в React компоненте

Я пытаюсь использовать Карту Google в React Компоненте, но она не работает. В настоящее время я имею в виду https://developers.google.com/maps/documentation/javascript/adding-a-google-map

Вот код, который у меня есть для моего компонента:

class ContactBody extends React.Component {
  componentWillMount() {
    const script = document.createElement("script");
    const API = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
    script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=initMap`;
    script.async = true;

    document.body.appendChild(script);
  };

  initMap() {
    const uluru = {lat: -25.363, lng: 131.044};
    const map = new google.maps.Map(document.getElementById('map'), {
      zoom: 4,
      center: uluru
    });
    const marker = new google.maps.Marker({
      position: uluru,
      map: map
    });
  }

  render() {
    
    this.initMap();
    
    return (
      <div>
        <h1>Contact</h1>
        <div id="map" style={{width: 400, height: 300}}></div>
      </div>
    )
  }
}

ReactDOM.render(
  <ContactBody />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>

Однако, когда я запускаю это, я получаю "Uncaught ReferenceError: Google не определен"

Может кто-нибудь сказать мне, что не так с моим кодом?

Спасибо.

5
Eunicorn

Вы добавляете тег <script> в свой документ для загрузки API Карт Google, но не ожидаете его фактической загрузки перед запуском метода initMap. Поскольку он еще не загружен, переменная google еще не существует.

Вы добавили параметр в URL скрипта callback со значением initMap. API Карт Google увидит это и запустит функцию под названием initMap, как только она будет готова. Но ваш initMap метод недоступен из глобальной области и поэтому не будет запущен.

Один из способов исправить свой код - сделать обещание для API Карт Google и разрешить это обещание с помощью (глобальной) функции обратного вызова, которую может запустить API Карт Google. Затем в коде компонента вы должны дождаться разрешения обещания, прежде чем продолжить.

Это может выглядеть примерно так:

class ContactBody extends React.Component {
  getGoogleMaps() {
    // If we haven't already defined the promise, define it
    if (!this.googleMapsPromise) {
      this.googleMapsPromise = new Promise((resolve) => {
        // Add a global handler for when the API finishes loading
        window.resolveGoogleMapsPromise = () => {
          // Resolve the promise
          resolve(google);

          // Tidy up
          delete window.resolveGoogleMapsPromise;
        };

        // Load the Google Maps API
        const script = document.createElement("script");
        const API = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
        script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=resolveGoogleMapsPromise`;
        script.async = true;
        document.body.appendChild(script);
      });
    }

    // Return a promise for the Google Maps API
    return this.googleMapsPromise;
  }

  componentWillMount() {
    // Start Google Maps API loading since we know we'll soon need it
    this.getGoogleMaps();
  }

  componentDidMount() {
    // Once the Google Maps API has finished loading, initialize the map
    this.getGoogleMaps().then((google) => {
      const uluru = {lat: -25.363, lng: 131.044};
      const map = new google.maps.Map(document.getElementById('map'), {
        zoom: 4,
        center: uluru
      });
      const marker = new google.maps.Marker({
        position: uluru,
        map: map
      });
    });
  }

  render() {
    return (
      <div>
        <h1>Contact</h1>
        <div id="map" style={{width: 400, height: 300}}></div>
      </div>
    )
  }
}

ReactDOM.render(
  <ContactBody />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>

14
tremby

для тех, кто получает ошибку, google не определен чуть выше ошибки, упомянутой eslint. 

const google = window.google;
3
Rida

Вот как я это сделал:

import React from 'react';

export default class GoogleMap extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      mapIsReady: false,
    };
  }

  componentDidMount() {
    const ApiKey = 'XXXXXXXXXXXXXXXXXXXX';
    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=${ApiKey}`;
    script.async = true;
    script.defer = true;
    script.addEventListener('load', () => {
      this.setState({ mapIsReady: true });
    });

    document.body.appendChild(script);
  }

  componentDidUpdate() {
    if (this.state.mapIsReady) {
      // Display the map
      this.map = new window.google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 12,
        mapTypeId: 'roadmap',
      });
      // You also can add markers on the map below
    }
  }

  render() {
    return (
      <div id="map" />
    );
  }
}
2
Michael Yurin

Попробуйте набрать это в верхней части страницы (работает для меня) -/* global google * /

0
Subhash Mudaliar