Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering a Google Map without react-google-map

Has anyone been able to render a google map using React and not using the react-google-map plugin? I'm trying something like this:

var MapTab = React.createClass({

render: function() {

    return  <div className="map-container">
       <div id='map' ></div>
     </div>

},

componentDidMount: function(){

        console.log("Hello")



window.onload = function(){
    (function initMap() {
        var markers = [];
        var geocoder = new google.maps.Geocoder();

        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 12,
            center: {lat: 37.7749300, lng: -122.4194200}
        });
    })(); 
}


}// end of cdm;
}); 
module.exports = MapTab;

Nothing I have tried has worked. I have tried capturing the map using refs as well but that did not render the map either. I have placed the google maps script in the header as well (with key) and have verified that the key is valid in a vanilla js project.

like image 377
trebek1 Avatar asked Jan 14 '16 00:01

trebek1


People also ask

Can I use Google Maps without API?

It's entirely possible to embed a responsive Google Map into a website without using a Google Map API.

How are Google Maps rendered?

Instead of trying to render a single image, Google breaks down the map into smaller tiles, and then places them next to each other to make up a single bigger picture — just like a mosaic. The primary reason for this is image size.

Is Google Maps API no longer free?

You won't be charged until your usage exceeds $200 in a month. Note that the Maps Embed API, Maps SDK for Android, and Maps SDK for iOS currently have no usage limits and are at no charge (usage of the API or SDKs is not applied against your $200 monthly credit).


2 Answers

With componentDidMount you know you map container div has loaded, but you are not guaranteed that the external maps api has loaded yet. Google provides you the option to give a callback function (initMap() in their examples).

https://maps.googleapis.com/maps/api/js?key=&callback=initMap

Now you can proceed as follows, After your map component did mount you can:

  1. window.initMap = this.initMap to make initMap from react available for Google maps to callback to.
  2. load the google maps JS with initMap parameter.
  3. In this.initMap in your component you can do your map stuff, because now you know your container ánd Google API have loaded.

    const React = require('react')
    const PropTypes = require('prop-types')
    import Reflux from 'reflux'
    const Radium = require('radium')
    
    class Map extends Reflux.Component {
    
        constructor(props) {
            super(props)
            this.loadJS = this.loadJS.bind(this)
            this.initMap = this.initMap.bind(this)
        }
    
        componentDidMount() {
            window.initMap = this.initMap;
            if (typeof google === 'object' && typeof google.maps === 'object') {
                this.initMap()
            } else {
                this.loadJS('https://maps.googleapis.com/maps/api/js?key=<API_KEY>&callback=initMap')   
            }
        }
    
        // https://github.com/filamentgroup/loadJS/blob/master/loadJS.js
        loadJS(src) {
            var ref = window.document.getElementsByTagName("script")[0];
            var script = window.document.createElement("script");
            script.src = src;
            script.async = true;
            ref.parentNode.insertBefore(script, ref);
        }
    
        initMap() {
            var map = new google.maps.Map(this.refs.map, {
              center: {lat: -34.397, lng: 150.644},
              zoom: 8
            })
        }
    
        render() {
            return (<div ref='map'></div>)
        }
    
    }
    module.exports = Radium(Map)
    
like image 175
Centillion Avatar answered Oct 12 '22 23:10

Centillion


get rid of window.onload. By the time componentDidMount method is called window is already loaded so your initMap() function never fires.

like image 32
Sasha Ko Avatar answered Oct 12 '22 22:10

Sasha Ko