Search code examples
reactjsleafletreact-leafletleaflet.markercluster

Leaflet-MarkerCluster refreshClusters() not working as expected


I can't get my custom Leaflet ClusterIcon to update when Marker data changes. The Markers have a custom option (let's call it isLight) and I need changes to that option to be reflected in the ClusterIcon.

In this example, I have two Markers – a dark and a light one:

Two different markers clustered Two different markers unclustered


Let's say the light one changes to dark, I want to update the cluster accordingly:

Two similar markers clustered Two similar markers unclustered


What's actually happening is that the ClusterIcon stays the same no matter which changes occur to the underlying Markers.

I have tried calling refreshClusters without arguments and with a list of markers, but it doesn't really do anything. Am I missing something?

Here's a codesandbox for the example above showcasing the problem: https://codesandbox.io/p/sandbox/fervent-sammet-lrhhq2

Because I am in a React app, I have worked around the issue by changing the MarkerClusterGroup key every time the data changes to make the clusters rebuild, but this is not a good solution because it updates unrelated clusters unnecessarily and causes the leaflet-ids to change. The latter should remain the same because of another issue.

The key-hack is commented out in the codesandbock. Feel free to uncomment it to see what I am trying to achieve.

Any help would be appreciated!


Solution

  • Unfortunately, React Leaflet does not treat all props as mutable/"dynamic", i.e. they are considered during creation, but their changes are not reflected later on in Leaflet objects:

    [Props] will not be updated in the UI when they change unless they are explicitly documented as being mutable.

    See explicit Marker dynamic props in v2.

    Custom props (like isLight in your case) are even less likely to be treated as mutable.

    Therefore you need to update them yourself directly on the underlying Leaflet object (here, the Marker options):

    setMarkerOneIsLight((value) => {
      const nextValue = !value;
      // Manually change the Marker options
      markerOneRef.current.leafletElement.options.isLight = nextValue;
      return nextValue;
    });
    

    Updated sandbox: https://codesandbox.io/p/sandbox/leaflet-cluster-icon-updates-forked-8ry5d3