Codementor Events

React for Google map Api

Published Aug 21, 2019
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:

2.JPG

Traffic layer:

3.JPG

Bicycling layer:

4.JPG

Discover and read more posts from DhananjayKumar
get started
post commentsBe the first to share your opinion
alekhya
a year ago

Can i get the same code with functional component otherthan class component

Show more replies