How to load the google maps api [removed] in my react app only when it is required?

前端 未结 3 438
渐次进展
渐次进展 2021-01-04 13:04

I want to try and use the google maps API to show a map but I\'m wondering if there\'s a better way to load the

相关标签:
3条回答
  • 2021-01-04 13:31

    Updates Oct 6, 2019: The example code is still working well, I have just updated them to use non-decorator syntax.


    This is what I make it worked in my recent project. I used react-async-script-loader component.

    import React from 'react';
    import scriptLoader from 'react-async-script-loader';
    
    class Maps extends React.Component {
      constructor(props) {
        super(props);
        this.map = null;
      }
    
      componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
        if (isScriptLoaded && !this.props.isScriptLoaded) {
          // load finished
          if (isScriptLoadSucceed) {
            this.map = new google.maps.Map(this.refs.map, {
              center: { lat: 10.794234, lng: 106.706541 },
              zoom: 20
            });
    
            if (navigator.geolocation) {
              navigator.geolocation.getCurrentPosition(
                position => {
                  const pos = {
                    lat: position.coords.latitude,
                    lng: position.coords.longitude
                  };
    
                  this.map.setCenter(pos);
    
                  const marker = new google.maps.Marker({
                    position: pos,
                    map: this.map,
                    title: 'Hello World!'
                  });
                },
                () => {
                  console.log('navigator disabled');
                }
              );
            } else {
              // Browser doesn't support Geolocation
              console.log('navigator disabled');
            }
          } else this.props.onError();
        }
      }
    
      render() {
        return (
          <div>
            <div ref="map" style={{ height: '80%', width: '100%' }}></div>
            {!this.map && <div className="center-md">Loading...</div>}
          </div>
        );
      }
    }
    
    export default scriptLoader(['https://maps.googleapis.com/maps/api/js?key=API_KEY'])(Maps);
    
    0 讨论(0)
  • 2021-01-04 13:40

    Thanks Nguyen Thanh. As google now in global scope I used window.google.

    import React, { Component } from 'react';
    import scriptLoader from 'react-async-script-loader';
    class Map extends Component{
        constructor(props) {
            super(props);
        }
        componentWillReceiveProps({isScriptLoadSucceed}){
            if (isScriptLoadSucceed) {
                var markers = [];
    
                var map = new window.google.maps.Map(document.getElementById('map'), {
                    zoom: 12,
                    center: {lat: 37.7749300, lng: -122.4194200}
                });
            }
            else{
                alert("script not loaded")
            }
        }
    
        render(){
            return(
                <div>
                    <div id="map" style={{height: "600px"}}></div>
                </div>
            )
        }
    }
    
    export default scriptLoader(
        ["https://maps.googleapis.com/maps/api/js?key= APIKEY"]
    )(Map)
    

    With react hook we can also load external script

    https://usehooks.com/useScript/

    //useScript custom hooks from the site
    
    let cachedScripts = [];
    
    function useScript(src) {
      // Keeping track of script loaded and error state
    
      const [state, setState] = useState({
        loaded: false,
        error: false
      });
    
      useEffect(
        () => {
          // If cachedScripts array already includes src that means another instance ...
          // ... of this hook already loaded this script, so no need to load again.
          if (cachedScripts.includes(src)) {
            setState({
              loaded: true,
    
              error: false
            });
          } else {
            cachedScripts.push(src);
            // Create script
            let script = document.createElement("script");
            script.src = src;
            script.async = true;
            // Script event listener callbacks for load and error
            const onScriptLoad = () => {
              setState({
                loaded: true,
                error: false
              });
            };
    
            const onScriptError = () => {
              // Remove from cachedScripts we can try loading again
              const index = cachedScripts.indexOf(src);
              if (index >= 0) cachedScripts.splice(index, 1);
              script.remove();
              setState({
                loaded: true,
                error: true
              });
            };
            script.addEventListener("load", onScriptLoad);
            script.addEventListener("error", onScriptError);
            // Add script to document body
            document.body.appendChild(script);
            // Remove event listeners on cleanup
            return () => {
              script.removeEventListener("load", onScriptLoad);
              script.removeEventListener("error", onScriptError);
            };
          }
        },
        [src] // Only re-run effect if script src changes
      );
      return [state.loaded, state.error];
    }
    
    
    

    Usage

    //App.js
    import React from "react";
    import ReactDOM from "react-dom";
    import { useState, useEffect } from "react";
    function App() {
      const [loaded, error] = useScript(
        "https://maps.googleapis.com/maps/api/js?key=API_KEY"
      );
      useEffect(() => {
        if (loaded) {
          new window.google.maps.Map(document.getElementById("map"), {
            zoom: 12,
            center: { lat: 37.77493, lng: -122.41942 }
          });
        }
      }, [loaded]);
    
      return (
        <div>
          <div>
            Script loaded: <b>{loaded.toString()}</b>
          </div>
          <div id="map" style={{ height: "600px" }} />
        </div>
      );
    }
    
    0 讨论(0)
  • 2021-01-04 13:43

    Yet another package react-dependent-script package to load Google Maps libraries, which provides the following features:

    • ensure to load the JavaScript and/or CSS first, then render your content
    • ensures the external content is only loaded once, regardless of how many times the render() function is called

    Here is a simple example, where you wrap your map component in ReactDependentScript component:

    <ReactDependentScript
          scripts={[
            "https://maps.googleapis.com/maps/api/js?key={YOUR-KEY-GOES-HERE}"
          ]}>
          <Map center={{ lat: -34.397, lng: 150.644 }} zoom={3} />
    </ReactDependentScript>
    

    Here is a demo for your reference

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题