【问题标题】:Add Google Map to GatsbyJS with Maps JavaScript API使用 Maps JavaScript API 将 Google 地图添加到 GatsbyJS
【发布时间】:2019-04-09 15:14:57
【问题描述】:

我正在尝试使用 Google Maps JavaScript API 将地图添加到我的 Gatsby 项目。

我是 customizing 盖茨比 html.js 通过默认副本的副本:

cp .cache/default-html.js src/html.js

然后,根据Google Maps Hello World example,经过一番谷歌搜索后,我发现我需要使用dangerouslySetInnerHTML,并在我关闭</body>标签之前添加以下内容html.js:

<script dangerouslySetInnerHTML={{
    __html: `
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8
        });
      }
    `
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap"
async defer></script>

(显然,用我的实际 API 密钥替换 MY_KEY

然后我在我的 React 组件中创建了一个空的 &lt;div id="map"&gt;&lt;/div&gt;

这行得通……有点。如果我导航离开,并返回到带有地图的页面,它就会消失。如果我重新加载它所在的页面,我只能看到地图。

有什么想法吗?

【问题讨论】:

    标签: reactjs google-maps gatsby


    【解决方案1】:

    这是我用来将 Google 地图纳入我的 Gatsby 构建的实现:

    import React from 'react';
    import GoogleMapReact from 'google-map-react';
    
    const isClient = typeof window !== 'undefined';
    
    export const GoogleMap = (props) => {
      const {
        address,
        googleMapsApiKey
      } = props;
      const lat = parseFloat(address.lat);
      const lng = parseFloat(address.lng);
      return (
        <section className="google-map">
          <div className="map">
            { isClient && (
              <GoogleMapReact
                bootstrapURLKeys={{ key: googleMapsApiKey }}
                defaultCenter={[lat, lng]}
                defaultZoom={14}
              >
                <div
                  className="marker"
                  lat={lat}
                  lng={lng}
                />
              </GoogleMapReact>
            )}
          </div>
        </section>
      );
    }
    

    注意isClient 条件渲染很重要,因此google-map-react 不会破坏您的 Gatsby 构建!

    【讨论】:

      【解决方案2】:

      我不确定这是否对你有帮助,但这是我所做的:

      1. cp .cache/default-html.js src/html.js
      2. 编辑src/html.js并将<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap" async defer></script>放在body标签的底部。
      3. 将地图初始化放在渲染#map的组件的componentDidMount()中。

      第 3 步可能如下所示:

      import React, { Component } from 'react'
      
      export default class Map extends Component {
        initMap = () => {
          new window.google.maps.Map(document.getElementById('map'), {
            center: { lat: 40, lng: 10 },
            zoom: 5,
          })
        }
      
        componentDidMount() {
          this.initMap()
        }
      
        render() {
          return <div id="map" />
        }
      }
      

      【讨论】:

      • 当我尝试这种方法时,我得到了TypeError: window.google is undefined
      • @Anders 确保您已正确包含脚本(请参阅步骤 2)——由于步骤 3 中的代码,这似乎不是错误。
      • 我确实正确地包含了它。结束使用 react-google-maps
      【解决方案3】:

      这是我如何在 Gatsby(第 1 版)上工作的:

      1. 我在定义我的 React 组件(在本例中为我的页面)之前定义了一个名为 initMap 的函数,如下所示
      if (typeof window !== 'undefined') {
        window.initMap = function() {
          new window.google.maps.Map(document.getElementById('map'), {
            center: { lat: 40, lng: 10 },
            zoom: 5,
          })
        }
      }
      

      注意: if (typeof window !== 'undefined') 是为了避免破坏服务器端呈现。在 ssr 期间,window 未定义,如果您不将该代码包装到 if 语句中,则会引发错误。

      1. 使用react-helmet我将谷歌地图脚本标签注入我的网站
      <Helmet>
        <script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap" async defer />
      </Helmet>
      

      就是这样。当脚本被加载(异步)时,它会调用initMap 回调并在div 内显示带有map id 的地图。

      [EDIT] 如果您只是想在其上显示地图以及一些静态标记和 infoWindow,这将非常有用。但是如果你需要给它添加一些动态内容,也许你的标记依赖于一些过滤器,我会推荐https://tomchentw.github.io/react-google-maps

      【讨论】:

      • 解决方案 2,通过 React Helmet 组件添加脚本是最好的解决方案,它在某种程度上是通过 react 处理导入的反模式。 Helmet 的目的是作为脚本加载的替代选择,并且应该已经在您的 Gatsby 模板中使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 2013-01-18
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多