Search code examples
javascriptreactjsgoogle-mapsfor-loopreact-google-maps

How can I render markers on a map in React using a for loop?


I'm experimenting with React, and I want to render a few markers on a map (I'm using Google Maps API). Now, everything is fine if I hardcode the markers (in the example, 5 markers, each with different coordinates, name and description, as in the locations array below). But what if i want to loop through the array and render them without hardcoding at all? I defined the renderMarkers function before the render(). Any help would be appreciated. Thanks!

/* Main component state */
state = {
    showingInfoWindow: false,
    activeMarker: {},
    selectedPlace: {},
    mapReady: true,
    desc: '',
    animation: null,
    locations: 
  [
   {
    "locationName": "name1",
    "position": '{"lat": "lat1", "lng": "lng1"}',
    "desc": "desc1"
  },
  {
    "locationName": "name2",
    "position": '{"lat": "lat2", "lng": "lng2"}',
    "desc": "desc2"
  },
  {
    "locationName": "name3",
    "position": '{"lat": "lat3", "lng": "lng3"}',
    "desc": "desc3"
  },
  {
    "locationName": "name4",
    "position": '{"lat": "lat4", "lng": "lng4"}',
    "desc": "desc4."
  },
  {
    "locationName": "name5",
    "position": '{"lat": "lat5, "lng": "lng5"}',
    "desc": "desc5."
  }
 ]
};

/* Function to render the markers, each with their relevant info taken from the state.locations array, on the map */
renderMarkers = () => {
for (let i = 0; i < this.state.locations.length; i++) {
  return <Marker
      onClick = { this.onMarkerClick }
      title = { this.state.locations[i].locName }
      position = { JSON.parse(this.state.locations[i].position) }
      desc = { this.state.locations[i].desc }
      animation = { this.state.animation[i] }
      name = { this.state.locations[i].locName } />
   }
 }

Solution

    1. Use map function to create an array of Markers.
    2. renderMarkers function should be put outside of the render function. Otherwise renderMarkers will be recreated each time the component's state is changed, because render is invoked on each state change (performance hit).

    renderMarkers() {
      return this.state.locations.map((location, i) => {
        return <Marker
          key={ i }
          onClick = { this.onMarkerClick }
          title = { location.locName }
          position = { JSON.parse(location.position) }
          desc = { location.desc }
          animation = { this.state.animation[i] }
          name = { location.locName } />
      })
    }
    
    render() {
      return <div>{ this.renderMarkers() }</div>
    }