How do I display multiple markers with react-google-maps

21,851

Solution 1

To display multiple markes all you have to do is iterate in a array with the marks positions.

{marks.map((mark, index) => <Marker key={index} position={mark} />)}

Here is a solution with a bit more functionality. The code snippet adds multiple circles on the map whenever the user clicks on it.

import React, { Component } from "react";
import { withScriptjs, withGoogleMap, GoogleMap, Circle } from "react-google-maps";

const Map = withScriptjs(
    withGoogleMap(props => (
        <GoogleMap
            defaultZoom={12}
            defaultCenter={{ lat: -34.397, lng: 150.644 }}
            onClick={e => props.onMapClick(e)}
        >
            {props.marks.map((mark, index) => (
                <Circle
                    key={index}
                    center={mark}
                    radius={1000}
                    options={{
                        strokeColor: "#66009a",
                        strokeOpacity: 0.8,
                        strokeWeight: 2,
                        fillColor: `#66009a`,
                        fillOpacity: 0.35,
                        zIndex: 1
                    }}
                />
            ))}
        </GoogleMap>
    ))
);

class ReportsPage extends Component {
    state = {
        marks: []
    };

    setMark = e => {
        this.setState({ marks: [...this.state.marks, e.latLng] });
    };

    deleteMarkS = () => {
        this.setState({
            marks: []
        });
    };

    render() {
        const { marks } = this.state;
        return (
            <div>
                <button onClick={this.deleteMark}>DELETE MARKS</button>
                <Map
                    googleMapURL="http://maps.googleapis.com/maps/api/js?key=[YOUR GOOGLE MAPS KEY]"
                    loadingElement={<div style={{ height: `100%` }} />}
                    containerElement={<div style={{ height: `400px` }} />}
                    mapElement={<div style={{ height: `100%` }} />}
                    onMapClick={this.setMark}
                    marks={marks}
                />;
            </div>
        );
    }
}

export default ReportsPage;

Don't forget to change [YOUR GOOGLE MAPS KEY] for you real key.

Solution 2

You need to pass an array of markers as a child to the GoogleMap component and map over them like so:

<GoogleMap>
{props.markers.map(marker => (
    <Marker
      position={{ lat: marker.latitude, lng: marker.longitude }}
      key={marker.id}
    />
))}
</GoogleMap>

See more information at https://github.com/tomchentw/react-google-maps#withgooglemap and https://tomchentw.github.io/react-google-maps/addons/marker-clusterer

Solution 3

I think you forgot to pass the prop marker2center in SimpleClickEventExampleGoogleMap component.

Take a look marker2center={this.state.marker2center}:

<SimpleClickEventExampleGoogleMap
  containerElement={
    <div style={{ height: `100%` }} />
  }
  mapElement={
    <div style={{ height: `100%` }} />
  }
  zoom={this.state.zoom}
  center={this.state.center}
  marker2center={this.state.marker2center}
  onMapMounted={this.handleMapMounted}
  onCenterChanged={this.handleCenterChanged}
  onMarkerClick={this.handleMarkerClick}
/>

Of course, if you are going to work with a thousand of markers you can use map so you don't need to manually put every marker inside the map.

Changing a bit would look like this:

<SimpleClickEventExampleGoogleMap
  containerElement={
    <div style={{ height: `100%` }} />
  }
  mapElement={
    <div style={{ height: `100%` }} />
  }
  zoom={this.state.zoom}
  center={this.state.center}
  markers={[MARKER1_CENTER, MARKER2_CENTER]}
  onMapMounted={this.handleMapMounted}
  onCenterChanged={this.handleCenterChanged}
  onMarkerClick={this.handleMarkerClick}
/>

const SimpleClickEventExampleGoogleMap = withGoogleMap(props => (
  <GoogleMap
    ref={props.onMapMounted}
    zoom={props.zoom}
    center={props.center}
    onCenterChanged={props.onCenterChanged}
  >
    {props.markers.map((marker, index)=> {
      return (
        <Marker
          position={marker}
          title="Click to zoom"
          onClick={props.onMarkerClick}
        />
      )
    })}
  </GoogleMap>
));

Solution 4

I used it in my code and fortunately it works!

/* global google */
import React, { Component } from 'react';
import {
    withScriptjs,
    withGoogleMap,
    GoogleMap,
    Marker,
    InfoWindow
} from 'react-google-maps';
import { compose, withProps } from 'recompose';

let markers=[
    {
        id:1,
        latitude: 25.0391667,
        longitude: 121.525,
        shelter:'marker 1'

    },
    {
        id: 2,
        latitude: 24.0391667,
        longitude: 110.525,
        shelter: 'marker 2'

    },
    {
        id: 3,
        latitude: 20.0391667,
        longitude: 100.525,
        shelter: 'marker 3'

    }
]
const MapWithAMarkerClusterer = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyAZN6EEeeaHPlqNx9fAV4YQgR7ksGNoWaQ&v=3.exp&libraries=geometry,drawing,places",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `100%` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    withScriptjs,
    withGoogleMap
)(props =>
    <GoogleMap
        defaultZoom={2}
        defaultCenter={{ lat: 25.0391667, lng: 121.525 }}
    >
        {markers.map(marker => {
            //const onClick = props.onClick.bind(this, marker)
            return (
                <Marker
                    key={marker.id}
                   
                    position={{ lat: marker.latitude, lng: marker.longitude }}
                >
                    <InfoWindow>
                        <div>
                            {marker.shelter}
                        </div>
                    </InfoWindow>
                </Marker>
            )
        })}
    </GoogleMap>
);

class googleMap extends Component {

    render() {
        return (
            <MapWithAMarkerClusterer />
        )
    }
}
export default googleMap;
Share:
21,851
Peter Weyand
Author by

Peter Weyand

Updated on July 09, 2022

Comments

  • Peter Weyand
    Peter Weyand almost 2 years

    I'm trying to display multiple markers using an npm package called react-google-maps and I'm having a difficult time. I'm following the demo here on how to display one map marker (https://tomchentw.github.io/react-google-maps/events/simple-click-event), however when I do the trivially understood thing of adding a second marker element to the the GoogleMap component I can't get that marker to display (I've also changed the coordinates). It's really bothering me and if anyone could point out what's going wrong I would really appreciate it.

    Thanks.

    Here is the code as I've fiddled with it. The only thing I've changed is added the second marker, with a new coordinate.

    /* global google */
    import {
      default as React,
      Component,
    } from "react";
    
    
    import withGoogleMap from './assets/withGoogleMap';
    import GoogleMap from './assets/GoogleMap';
    import Marker from './assets/Marker';
    
    const SimpleClickEventExampleGoogleMap = withGoogleMap(props => (
      <GoogleMap
        ref={props.onMapMounted}
        zoom={props.zoom}
        center={props.center}
        onCenterChanged={props.onCenterChanged}
      >
        <Marker
          defaultPosition={props.center}
          title="Click to zoom"
          onClick={props.onMarkerClick}
        />
    
        <Marker
          defaultPosition={props.marker2center}
          title="Click to zoom"
          onClick={props.onMarkerClick}
        />
    
    
    
      </GoogleMap>
    ));
    
    const INITIAL_CENTER = { lat: -25.363882, lng: 131.044922 };
    const MARKER1_CENTER = { lat: -25.363882, lng: 131.044922 };
    const MARKER2_CENTER = { lat: -25.44, lng: 131.55 };
    
    /*
     * https://developers.google.com/maps/documentation/javascript/examples/event-simple
     *
     * Add <script src="https://maps.googleapis.com/maps/api/js"></script> to your HTML to provide google.maps reference
     */
    export default class SimpleClickEventExample extends Component {
    
    
    
      state = {
        zoom: 4,
        center: INITIAL_CENTER,
        marker2center: MARKER2_CENTER
      };
    
      handleMapMounted = this.handleMapMounted.bind(this);
      handleCenterChanged = this.handleCenterChanged.bind(this);
      handleMarkerClick = this.handleMarkerClick.bind(this);
    
      handleMapMounted(map) {
        this._map = map;
      }
    
      handleMarkerClick() {
        this.setState({
          zoom: 8,
        });
      }
    
      handleCenterChanged() {
        const nextCenter = this._map.getCenter();
        if (nextCenter.equals(new google.maps.LatLng(INITIAL_CENTER))) {
          // Notice: Check nextCenter equality here,
          // or it will fire center_changed event infinitely
          return;
        }
        if (this._timeoutId) {
          clearTimeout(this._timeoutId);
        }
        this._timeoutId = setTimeout(() => {
          this.setState({ center: INITIAL_CENTER });
          this._timeoutId = null;
        }, 3000);
    
        this.setState({
          // Because center now is a controlled variable, we need to set it to new
          // value when "center_changed". Or in the next render it will use out-dated
          // state.center and reset the center of the map to the old location.
          // We can never drag the map.
          center: nextCenter,
        });
      }
    
      componentWillUnmount() {
        if (this._timeoutId) {
          clearTimeout(this._timeoutId);
        }
      }
    
      render() {
        return (
          <div className='googleMap' style={{width: "500px", height: "500px", margin: "0 auto"}}>
            <SimpleClickEventExampleGoogleMap
              containerElement={
                <div style={{ height: `100%` }} />
              }
              mapElement={
                <div style={{ height: `100%` }} />
              }
              zoom={this.state.zoom}
              center={this.state.center}
              onMapMounted={this.handleMapMounted}
              onCenterChanged={this.handleCenterChanged}
              onMarkerClick={this.handleMarkerClick}
            />
          </div>
        );
      }
    }
    
  • Rob L
    Rob L over 6 years
    That link is no longer valid
  • Broda Noel
    Broda Noel over 6 years
    Thank you @user3270407! Link fixed.
  • rohan-patel
    rohan-patel about 6 years
    Could not find marker2center in the documentation. Could you possibly provide little more detail what exactly it does?
  • Thiago
    Thiago about 6 years
    @rohan-patel marker2center is a prop created by the original creator of this question! That's why you cannot find it in the documentation!
  • rohan-patel
    rohan-patel about 6 years
    That makes sense. 🤦🏽‍♂️
  • Lachezar Raychev
    Lachezar Raychev over 4 years
    This does not work me, saddly. If I do not use &callback=_google_map_loaded_cb at the end of my googleMapURL from all the markers in the array only the first one is printed. If I use callback in the url I get these errors: You have included the Google Maps JavaScript API multiple times on this page.This may cause unexpected errors. and Uncaught (in promise)
  • Lachezar Raychev
    Lachezar Raychev over 4 years
    Any Idea how to fix this ?