Второй раздел моего свадебного веб-сайта предназначен для отображения всей информации, связанной с местом проведения свадьбы: где будет проходить церемония, как туда добраться, а также некоторые предложения, где остановиться.

Это статический компонент, поскольку вся необходимая информация жестко закодирована. Основной план включает в себя несколько фотографий местности, описание места и способы добраться до него. Чтобы улучшить свои навыки React, что является основной причиной, по которой я работаю над этим проектом, я решил включить Google Maps в этот раздел. Это сделано для визуального отображения основных мест проведения свадьбы на интерактивной карте.

Реализовать эту функцию можно разными способами:

  1. просто добавив снимок экрана или встроенную карту Google
  2. используя пакет, который предоставляет предварительно разработанный компонент React для отображения карты
  3. работаю с API Карт Google для создания собственного компонента карты.

Встроенная карта не обеспечивала тот тип интерактивности, который я хотел для моих пользователей, а компонент React не давал мне слишком большой гибкости в отношении стиля. Фактически, готовый компонент поставляется уже завернутым в div с абсолютным позиционированием, и я не смог найти способ стилизовать этот внешний div (, если вы когда-либо использовали google-react-maps, а вы знаете, как вносить изменения в оболочку, обращайтесь).

С помощью документации Google Maps API и видеоурока от Yahya Elharony я смог создать свой собственный компонент Карта с серией маркеров с собственным информационным окном. Местоположение хранится в состоянии компонента, так как в будущем я мог бы разрешить пользователям добавлять свои собственные местоположения на карту.

Документация по API Карт предельно ясна, но написана для JavaScript, а не React. Самым сложным было понять, как загрузить Maps JavaScript API в приложение React. В простом приложении JavaScript мы бы добавили тег скрипта и его содержимое непосредственно перед закрывающим тегом body в файле HTML, однако как это работает в проекте React? Решение состоит в том, чтобы создать функцию, которая генерирует скрипт для загрузки API Карт, а затем вызывать ее из нашего компонента Карты.

Это тег скрипта, представленный в Руководстве по Maps JavaScript:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
    async defer></script>

В нашем файле Map.js вне компонента, но до объявления экспорта по умолчанию, мы создаем функцию с именем loadScript, которая принимает URL-адрес в качестве единственного параметра. Первая строка этой функции сохранит первый тег скрипта нашего документа в переменную с именем index. Строки 3–6 создадут сценарий, описанный Maps JavaScript API, а последняя строка вставит наш сценарий перед сценарием индекса в его родительском узле. Это сохранит наш сценарий в самом начале нашего списка сценариев.

function loadScript(url) {
 var index = window.document.getElementsByTagName(“script”)[0];
 var script = window.document.createElement(“script”);
 script.src = url;
 script.async = true;
 script.defer = true;
 index.parentNode.insertBefore(script, index);
}

Затем мы вызываем эту функцию из нашего компонента и передаем URL-адрес, заполненный нашим ключом API, в качестве параметра. Это полный код для простого компонента Map, в котором я также создал стиль const для управления стилем карты (позже я решил переместить стиль в отдельный файл Map.css, так как я также хотел стилизовать информационные окна) .

Теперь давайте добавим маркеры в собственное информационное окно. Как уже упоминалось, на данный момент местоположения жестко запрограммированы и хранятся в массиве с именем mapLocation в состоянии компонента Map.

Внутри функции initMap () мы пройдемся по локациям в состоянии и создадим маркер для каждого из них с помощью конструктора google.maps.Marker.

this.state.mapLocations.map(location => {
const marker = new window.google.maps.Marker({
        position: { 
            lat: location.position.lat, 
            lng:   location.position.lng 
        },
        map: map,
        title: location.title
      });
    });

Следующим шагом является создание информационного окна для каждого из местоположений, в котором будет отображаться ряд информации. Мы можем определить, какой контент будет отображаться в переменной contentString, которую мы создадим внутри цикла. Например, в моем случае я включил название места, краткое описание и изображение. Затем я применил стиль для информационного окна в файле Map.css. Информационное окно не появится, если мы не свяжем его с маркером через событие щелчка: только при щелчке по маркеру откроется информационное окно.

this.state.mapLocations.map(location => {
  const infowindow = new window.google.maps.InfoWindow(
     content: contentString);
  const contentString = `<div class="container">
      <h2>${location.name}</h2>
      <p>${location.description}</p>
      <img src="${location.image}" /></div>`;
  const marker = new window.google.maps.Marker({
        position: { 
            lat: location.position.lat, 
            lng:   location.position.lng 
        },
        map: map,
        title: location.title
      });
  marker.addListener("click", function() {
        infowindow.open(map, marker);
      });
    });

Однако этот код представляет небольшую проблему: все информационные окна останутся открытыми, если мы не нажмем крестик в правом верхнем углу всплывающего окна, чтобы закрыть каждое из них. Чтобы решить эту проблему, мы можем переместить информационное окно const за пределы цикла после удаления его содержимого, а затем мы можем добавить следующую функцию в функцию прослушивателя событий, которую мы объявили в нижней части нашего цикла:

marker.addListener("click", function() {
    infowindow.setContent(contentString);
    infowindow.open(map, marker);
      });
    });

Окончательный код для компонента карты здесь, включая маркеры и информационные окна:

Вот так страница выглядит на данный момент. Следующим шагом будет работа над формой RSVP и ее интеграция с Firebase.

Ресурсы, используемые для этого раздела сайта:

Учебник по Google Maps API - очень полезная документация по Google Maps API. Я снова воспользуюсь этой страницей для изменения значков на карте.

Youtube-учебник от Yahya Elharony - Реализация API Карт Google очень четко объясняется в этом видео-руководстве (5 частей).