React for Google map Api
Got a requirement to use React and google maps to display traffic, bike and transit layers using the google api. Did a quick research on available custom library (listed below) but couldn't find any to achieve the same.
- google-maps-react
- react-google-maps
- react-google-maps-api
Then gave a try to use Google map JS API so that I could extend the solution whatever way I want and after that I won't be dependent on Custom libraries. Source Code can be downloaded from github repository react-google-map.
First created a Map component which take id, options and onMapLoaded callback. Important point to note here is that JS file is loaded on demand. There are other 3rd party react library available like react-load-script which can also be used but in this example I am using plain vanila java script to achieve the same. Another nice post on the loading script dynamically is available here.
Map.cs
import React, { Component } from 'react';
class Map extends Component {
constructor(props) {
super(props);
this.onScriptLoad = this.onScriptLoad.bind(this)
}
onScriptLoad() {
const map = new window.google.maps.Map(document.getElementById(this.props.id),this.props.options);
this.props.onMapLoad(map)
}
componentDidMount() {
if (!window.google) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = `https://maps.google.com/maps/api/js?key=AIzaSyAyesbQMyKVVbBgKVi2g6VX7mop2z96jBo`;
script.id = 'googleMaps';
document.body.appendChild(script);
script.addEventListener('load', e => {
this.onScriptLoad()
})
}
else {
this.onScriptLoad()
}
}
render() {
return (
<div style={{ width: 500, height: 500 }} id={this.props.id} />
);
}
}
export default Map;
Now the map can be plotted just by including this in App.js
<Map id="myMap" options={{center: { lat: 51.501904, lng: -0.115871 }, zoom: 13}} onMapLoad = {this.handleMapLoad}/>
Requirement was to add layers to the plotted map based on button click event. So in handleLayer callback I have setting layer on the plotted map. Full code will look like this.
App.js
import Map from './Map';
import React from 'react';
import {Component} from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
map: {},
traffic : {},
transit : {},
bicycling : {}
}
}
handleMapLoad = (map) => {
this.setState({
map: map,
traffic : new window.google.maps.TrafficLayer(),
transit : new window.google.maps.TransitLayer(),
bicycling : new window.google.maps.BicyclingLayer(),
})
}
handleLayer = (layer) => {
console.log(this.state.map);
switch (layer) {
case "traffic" :
this.state.transit.setMap(null);
this.state.bicycling.setMap(null);
this.state.traffic.setMap(this.state.map);
break;
case "transit" :
this.state.bicycling.setMap(null);
this.state.traffic.setMap(null);
this.state.transit.setMap(this.state.map);
break;
case "bicycling" :
this.state.transit.setMap(null);
this.state.traffic.setMap(null);
this.state.bicycling.setMap(this.state.map);
break;
case "none" :
this.state.transit.setMap(null);
this.state.traffic.setMap(null);
this.state.bicycling.setMap(null);
break;
}
}
render() {
return (
<>
<button onClick = {() => this.handleLayer("transit")}> Transit</button>
<button onClick = {() => this.handleLayer("traffic")}> Traffic</button>
<button onClick = {() => this.handleLayer("bicycling")}> Bicycling</button>
<button onClick = {() => this.handleLayer("none")}> None</button>
<Map
id="myMap"
options={{
center: { lat: 51.501904, lng: -0.115871 },
zoom: 13
}}
onMapLoad = {this.handleMapLoad}
/>
</>
);
}
}
export default App;
We are done here. Now run application by npm start and click on the button at the top of the map.
Transit layer:
Traffic layer:
Bicycling layer:
Can i get the same code with functional component otherthan class component