2

I'm trying to take an array of objects with lat/long points and create a Marker for each, and then pass those Markers into a <MarkerClusterer> component.

By copying straight off the docs here I can make it work. However, their approach is a bit different from what I need.

The difference seems to be with how the points are mapped to the component.

Working code:

<MarkerClusterer
      options={{imagePath:"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m"}}
    >
      {
        (clusterer) => [
          {lat: -31.563910, lng: 147.154312},
          {lat: -33.718234, lng: 150.363181},
          {lat: -33.727111, lng: 150.371124},
          {lat: -33.848588, lng: 151.209834}
        ].map((location, i) => (
          <Marker
            key={i}
            position={location}
            clusterer={clusterer}
          />
        ))
      }
    </MarkerClusterer>

My non-working code:

const listings = [
    { lat: -31.56391, lng: 147.154312 },
    { lat: -33.718234, lng: 150.363181 },
    { lat: -33.727111, lng: 150.371124 },
    { lat: -33.848588, lng: 151.209834 },
  ];
  let testArray = [];
  for (let i = 0; i < listings.length; i++) {
    let location = listings[i];
    testArray.push(
      <Pin position={location} id={i} key={i} clusterer={listings} />
    );
  }
...

 <MarkerClusterer>
    {testArray}
 </MarkerClusterer>

And here is a codesandbox with an example. Code is under Map2.js and the difference is at line 61.

I can't figure out what the first approach is doing that I'm not. Maybe the clusterer reference? Any help in that area will be greatly appreciated.

colemars
  • 979
  • 3
  • 12
  • 25

1 Answers1

5

The <MarkerClusterer> component requires a function as its child prop. That function will be called by the <MarkerClusterer> component's render function. In the second case, you are passing an array as the child prop. Hence the MarkerClusterer is trying to invoke your array as a function (testArray()) and hence failing.

this should work

<MarkerClusterer
  options={{
    imagePath:
      "https://developers.google.com..."
  }}
>
  {clusterer =>
    listings.map((location, i) => (
      <Pin key={i} position={location} clusterer={clusterer} />
    ))
  }
</MarkerClusterer>

This is known as render props in the react world. Read here for more details.

johnny peter
  • 4,634
  • 1
  • 26
  • 38