× TypeError: Cannot read property ‘maps’ of undefined – google.maps is undefined (React)

I’m having an error while using google maps js API, every few loads I’m getting this error.

TypeError: Cannot read property ‘maps’ of undefined (anonymous function) src/features/landingPage/components/LandingPageMap.js:10

The Map Component

const LandingPageMap = (props) => {
const { center, zoom, reports } = props;
const mapRef = useRef();

useEffect(() => {
   const map = new window.google.maps.Map(mapRef.current, {
    center: center,
    zoom: zoom,
    disableDefaultUI: true,
  });
 }, [center, zoom, reports]);

return (
 <>
   <div
    ref={mapRef}
    className={`map ${props.className}`}
    style={props.style}
  >
    Loading map...
  </div>
</>
 );
};

  export default LandingPageMap;

I’m getting the Google map API in the index.html file inside the head tag.

 <script async
src="https://maps.googleapis.com/maps/api/js?key=GOOGLE-MAPS-API-KEY&libraries=places&callback=initMap">
 </script>

I’m not sure how to solve this problem. Thank you for your time and help.

Answer

When using frameworks, loading the Maps Javascript API is not as simple as putting it in the index.html unlike in vanilla javascript. One way to do this and not rely on 3rd party libraries is to instead load the script dynamically in the map component.

Here is a simple working sample for your reference or see below for the code: https://stackblitz.com/edit/react-simple-map-ek1igt

App.js

    import React, { Component } from 'react';
    import { render } from 'react-dom';
    import Map from './components/map';
    import "./style.css";
    
    class App extends Component {
     
      render() {
        return (
           <Map 
            id="myMap"
            options={{
              center: { lat: -33.8569, lng: 151.2152 },
              zoom: 8
            }}
          />
        );
      }
    }
    
    export default App;

map.js

    import React, { Component } from 'react';
    import { render } from 'react-dom';
    
    class Map extends Component {
       constructor(props) {
        super(props);
      }
    
      onScriptLoad() {
        const map = new window.google.maps.Map(
          document.getElementById(this.props.id),
          this.props.options);
      }
    
      componentDidMount() {
        if (!window.google) {
          var s = document.createElement('script');
          s.type = 'text/javascript';
          s.src = `https://maps.google.com/maps/api/js?key=YOUR_API_KEY`;
          var x = document.getElementsByTagName('script')[0];
          x.parentNode.insertBefore(s, x);
          // Below is important. 
          //We cannot access google.maps until it's finished loading
          s.addEventListener('load', e => {
            this.onScriptLoad()
          })
        } else {
          this.onScriptLoad()
        }
      }
    
      render() {
        return (
          <div className="map" id={this.props.id} />
        );
      }
    }
    
    export default Map