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.creat
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:
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)
You can render a google map easily using React Refs Which are an ideal solution when integrating with third party libraries. Like this:
class App extends React.Component {
constructor(props){
super(props)
this.state = {
// no state for now..
}
// Use createRef() to create a reference to the DOM node we want
this.myMapContainer = React.createRef()
}
componentDidMount() {
// Instead of using: document.getElementById, use the ref we created earlier to access the element
let map = new google.maps.Map(this.myMapContainer.current, {
center: { lat: -34.9973268, lng: -58.582614 },
scrollwheel: false,
zoom: 4
})
}
render() {
return (
<div className="container">
<div ref={this.myMapContainer} id="map"></div>
<div id="text"><p>Google Maps now requires the use of a valid API Key.
That's why you see the popup window "This page can't load Google Maps correctly."</p>
<a href="https://developers.google.com/maps/documentation/javascript/get-api-key">Go get one!</a>
</div>
</div>
)
}
}
Working Example here
Note: Don't forget to place the <script>
that makes the call to the Google Maps API. If you created your project using create-react-app, you can place the script inside of public/index.html
get rid of window.onload
. By the time componentDidMount
method is called window is already loaded so your initMap()
function never fires.
It seems that you are not familiar with React Component Life Cycle yet.
https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle
or this: http://busypeoples.github.io/post/react-component-lifecycle/ (this has the table of order in which react's methods are executed)
Actually, in the componentDidMount() ("DID-mount" means the element has already been there on the page, so you can start binding events to it)
React Component's idea is interesting, so we don't need to use javascript's "window.onload()" or jQuery's "$(document).ready()"
Therefore, your code can be revised as follows:
render: function() {
return <div className="map-container">
<div id='map' ></div>
</div>
},
componentDidMount: function(){
console.log("Hello")
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;
PS: Besides, in order to make the map appear, you need to style the map-container and map correctly (which need a height in pixel, in your case of "0 px width, maybe you need to put the width, too - either in px or 100%) Feel free to style them, though!