Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OverlayViews are added to a surrounding MarkerClusterer but not removed on unmount #301

Closed
camiel opened this issue Jul 16, 2016 · 9 comments

Comments

@camiel
Copy link
Contributor

camiel commented Jul 16, 2016

For Markers the MarkerCreator adds the marker to the surrounding MarkerClusterer (https://github.com/tomchentw/react-google-maps/blob/master/src/creators/MarkerCreator.js#L77). In the Marker component the marker is removed from this clusterer when componentWillUnmount is called: (https://github.com/tomchentw/react-google-maps/blob/master/src/Marker.js#L98). For OverlayViews the OverlayViewCreator does add the view to the surrounding MarkerClusterer (https://github.com/tomchentw/react-google-maps/blob/master/src/creators/OverlayViewCreator.js#L189), but it is never removed. Because of this OverlayViews remain in the clusterer while they should have been removed.

To illustrate this bug with an example, which is added to the gh-pages example project in https://github.com/camiel/react-google-maps/tree/bug-marker-clusterer-overlay-view, consider this component that always renders 10 overlay views in a MarkerClusterer. Every 1 second one OverlayView is removed while a new one is added. Due to the bug the cluster will keep growing instead.

import { default as React, Component } from "react";

import { GoogleMap, OverlayView } from "react-google-maps";

import { default as MarkerClusterer } from "react-google-maps/lib/addons/MarkerClusterer";

const STYLES = {
  mapContainer: {
    height: `100%`,
  },
  overlayView: {
    background: `red`,
    border: `1px solid #ccc`,
    width: 25,
    height: 25,
  },
};

export default class ClusteredOverlayViewBugExample extends Component {
  state = {
    startPosition: 0,
    shiftInterval: null,
  }

  componentWillMount() {
    this.setState({
      shiftInterval: setInterval(this.shiftStartPosition.bind(this), 1000),
    });
  }

  componentWillUnmount() {
    clearInterval(this.state.shiftInterval);
  }

  shiftStartPosition() {
    this.setState({
      startPosition: this.state.startPosition + 1,
    });
  }

  render() {
    return (
      <GoogleMap
        containerProps={{ ...this.props, style: STYLES.mapContainer }}
        defaultZoom={8}
        defaultCenter={{ lat: -34.397, lng: 150.644 }}
      >
        <MarkerClusterer>
          {Array
            .from(new Array(10))
            .map((_, i) => (i + this.state.startPosition) % 100)
            .map(i =>
              <OverlayView
                key={i}
                position={{ lat: -34.397, lng: 150.644 }}
                mapPaneName={OverlayView.MARKER_LAYER}
              >
                <div style={STYLES.overlayView}></div>
              </OverlayView>
            )}
        </MarkerClusterer>

      </GoogleMap>
    );
  }
}
@tomchentw
Copy link
Owner

Released v5.1.1

@tomchentw
Copy link
Owner

@camiel why would you need to render <OverlayView> specifically under <MarkerClusterer>? Is there any benefits for this?

@camiel
Copy link
Contributor Author

camiel commented Oct 4, 2016

@tomchentw I needed it for custom markers for which regular markers are too limited but I still required clustering.

@tomchentw
Copy link
Owner

@camiel Got it. Unfortunately, I removed this feature in the6.0.0 version. It would be great if you can take a look at new changes and if you like, submit a new PR with a demo page. It should be easier to do it in 6.0.0

Also, 6.0.0 is released on npm beta tag now. We also have a new demo page. Feel free to try it:
https://tomchentw.github.io/react-google-maps/

@amangeot
Copy link
Contributor

Hi @camiel, hi @tomchentw, I'm using custom markers with MarkerClusterer too. I am currently trying to change the marker's color on click.

I'm changing the marker's icon on click, I see in logs that GoogleMap and MarkerClusterer get updated (react lifecycle), but the map / icons display doesn't change.
If i refresh the entire page, the previously clicked marker's icon shows it's selected (identified in URL).

Do you have any suggestion on how one can update the marker icons on clicks ? Should I use OverlayView to fake a change of icon ? Do you know why the map display doesn't update ?

@amangeot
Copy link
Contributor

Well I eventually tried OverlayView and it works very well, even with 8000 clustered markers that are in a separate React smart component.

In case anyone would be looking for it, this works to put a highlighted marker in place of a clicked one:

      <GoogleMap>
        <OverlayView position={{ lat, lng }}
          getPixelPositionOffset={this.getPixelPositionOffset}
          defaultMapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}>
          <img style={{ display: markerOnPreview ? 'initial' : 'none' }} src={markerAccentIcon} />
        </OverlayView>
        <YourSmartClusterer onMarkerClick={this.handleMarkerClick} />
      </GoogleMap>

@barnc
Copy link

barnc commented Apr 2, 2017

Does anyone have a working example of a clusterer with custom overlayviews for each marker? I'm struggling to find anything concrete on this.

@tomchentw
Copy link
Owner

Please refer to Getting Help section in the README (or #469).

@israellev
Copy link

I seem that if this link don't work:
import { default as MarkerClusterer } from "react-google-maps/lib/addons/MarkerClusterer";

better you try this:
import { default as MarkerClusterer } from "react-google-maps/lib/components/addons/MarkerClusterer";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants