Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load the google maps api <script> in my react app only when it is required?

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 <script> tag than putting it in my index.html.

I would like for the script to load only when I go to the /map route. So, I would want to remove it from my index.html and load it dynamically. However, I also want to make sure that if its already been loaded that I don't try and load it again.

I'm not sure if there is a library to handle this. What I've tried so far (but failed) is to create a loadScript function which appends a <script> to the actual dom and assigns it a key so in this case 'google-maps.

Thanks

like image 674
user1354934 Avatar asked Jan 18 '17 01:01

user1354934


People also ask

How to load Google Maps in react app using JavaScript?

If you don’t know about how to create a react application then refer the below link. 2. Generate google maps API key We need to create Google Maps API key to load the map in DOM with the help of JavaScript API. Refer below link for it. 3. Load google maps script To load google map, we need to load the google maps script first.

How to use googleapiwrapper hoc with react?

Alternatively, the GoogleApiWrapper HOC can be configured by passing a function that will be called with the wrapped component’s props and should return the configuration object like so: At this point, you have a Google Map in your React application.

How to create a Google map with markers using React-Google-Maps?

The map component is built using react-google-maps. The library allows us to easily set-up a Google map with markers. Install the module in the project; <small id="addressHelp" className="form-text text-muted">The street address that you want to look-up, in the format used by the national postal service of the country concerned.

How do I get Started with the Google Maps JavaScript API?

Before you begin: Before you start using the Maps JavaScript API, you need a project with a billing account and the Maps JavaScript API enabled. To learn more, see Get Started with Google Maps Platform . The Maps JavaScript API lets you customize maps with your own content and imagery for display on web pages and mobile devices.


2 Answers

As of April 2021 Google has "made it easier to use the Maps JavaScript API in modern web apps" more details on their blog post: Loading Google Maps Platform JavaScript in Modern Web Applications.

This are the instructions for the Google Maps JavaScript API Loader library

import { Loader } from '@googlemaps/js-api-loader';

const loader = new Loader({
  apiKey: "",
  version: "weekly",
  libraries: ["places"]
});

const mapOptions = {
  center: {
    lat: 0,
    lng: 0
  },
  zoom: 4
};

// Promise
loader
  .load()
  .then((google) => {
    new google.maps.Map(document.getElementById("map"), mapOptions);
  })
  .catch(e => {
    // do something
  });

Or if you want, you can use the Google Maps JavaScript API React Wrapper library.

like image 72
lmiguelmh Avatar answered Sep 21 '22 06:09

lmiguelmh


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>
  );
}
like image 40
saiful619945 Avatar answered Sep 19 '22 06:09

saiful619945