react-google-maps-api icon indicating copy to clipboard operation
react-google-maps-api copied to clipboard

MarkerF does not update the marker color after modification

Open SLachiheb opened this issue 1 year ago • 10 comments

Environment

  • os: linux
  • node: v16.15.0
  • next.js : 12.1.6
  • react version : 18.2.0
  • @react-google-maps/api version: 2.12.1

Feature:

I use a function that dynamically changes the color assigned to a marker, but the problem is that the marker does not change, it keeps its initial color, it does not get updated. I use the "MarkerF" instead of the "Marker". Before I was on react 17 and I used "Marker" and the color change was done without any problem.

I'm under the impression that you can't change the characteristics of the MarkerF after you build it, hence the problem I'm having with changing the color at runtime.

How does it behave?

The marker does not change color.

How should it behave correctly?

The marker should dynamically take the selected color.

Code

const [cell, setCell] = useState<{color : string, posGPS : {lat : number, lng: number}>({color : '#fff', posGPS : {lat : ..., lgn : ...});

... color update function with setCell

<MarkerF icon={{ path: 'M11 22C17.0751 22 22 17.0751 22 11C22 4.92487 17.0751 0 11 0C4.92487 0 0 4.92487 0 11C0 17.0751 4.92487 22 11 22Z', fillColor: cellule.color, fillOpacity: 1, }} position={cellule.posGPS} />

SLachiheb avatar Jul 19 '22 08:07 SLachiheb

@SLachiheb I am facing the same issue. Have you been able to find the solution for it?

Sheraz064-ai avatar Aug 21 '22 13:08 Sheraz064-ai

also experiencing this issue - so far I've had to just generate a random key for the marker so it always rerenders, but this is obviously terrible for performance 😅

EskiMojo14 avatar Sep 01 '22 10:09 EskiMojo14

+1 to this issue.

ShawnCentra avatar Oct 11 '22 19:10 ShawnCentra

Also experiencing this issue.

alexandre1921 avatar Nov 17 '22 14:11 alexandre1921

I've run into same issue today. I went through <MarkerF /> source code and I've found out that icon is set only once, during first render (causing this issue).

The way I solved this issue was to create a wrapper component over MarkerF and add some logic. MarkerF accepts onLoad property which you can use to grab and store the marker reference. The next step is to simply call setIcon on marker reference and pass an updated icon whenever you wish to change it.

Demo:

import { useEffect, useRef } from 'react';
import { MarkerF } from '@react-google-maps/api';

function Marker({ color }) {
  const markerRef = useRef(null);

  const handleOnLoad = (markerInstance) => {
    markerRef.current = markerInstance;
  };

  useEffect(() => {
    if (markerRef.current) {
      markerRef.current.setIcon(markerIconFactory(color));
    }
  }, [color]);

  return <MarkerF onLoad={handleOnLoad} icon={markerIconFactory(color)} />;
}

const markerIconFactory = (color) => ({
  path: 'M11 22C17.0751 22 22 17.0751 22 11C22 4.92487 17.0751 0 11 0C4.92487 0 0 4.92487 0 11C0 17.0751 4.92487 22 11 22Z',
  fillColor: color,
});

Hope it helps

deivuss331 avatar Nov 17 '22 18:11 deivuss331

Amazing, this will work as a workaround, thank you @deivuss331 😁.

alexandre1921 avatar Nov 17 '22 23:11 alexandre1921

thanks a lot, you've saved my day! 😁 @deivuss331

ceyton avatar Nov 19 '22 13:11 ceyton

You can update the icon by setting the value in the options prop instead.

<MarkerF
  key={marker.id}
  position={{ lat: marker.lat, lng: marker.lng }}
  options={{
    zIndex: marker.id === id ? 1 : 0,
    icon:
      marker.id === id
        ? "./map-pin-icon-red.svg"
        : "./map-pin-icon-blk.svg",
  }}
/>

VinitSarvade avatar Nov 30 '22 03:11 VinitSarvade

Thank you so much You save two life.. @VinitSarvade

jthw1005 avatar May 09 '23 03:05 jthw1005

@VinitSarvade Thank you. By the way do you (or anyone else) know if it is possible to change the size of .webp/.svg/.png (or whatever is used for custom marker) used in options.icon prop? I mean no the original size but through the props

fuelkoy avatar May 17 '23 12:05 fuelkoy

You can update the icon by setting the value in the options prop instead.

<MarkerF
  key={marker.id}
  position={{ lat: marker.lat, lng: marker.lng }}
  options={{
    zIndex: marker.id === id ? 1 : 0,
    icon:
      marker.id === id
        ? "./map-pin-icon-red.svg"
        : "./map-pin-icon-blk.svg",
  }}
/>

So, @VinitSarvade , do you by any change have an explanation for why we have to do it like this? Would be very much appreciated :)

Fabioni avatar Feb 07 '24 09:02 Fabioni

You can update the icon by setting the value in the options prop instead.

<MarkerF
  key={marker.id}
  position={{ lat: marker.lat, lng: marker.lng }}
  options={{
    zIndex: marker.id === id ? 1 : 0,
    icon:
      marker.id === id
        ? "./map-pin-icon-red.svg"
        : "./map-pin-icon-blk.svg",
  }}
/>

So, @VinitSarvade , do you by any change have an explanation for why we have to do it like this? Would be very much appreciated :)

As @deivuss331 has mentioned in his comment - "icon is set only once, during first render (causing this issue)". Changing the icon value on a state change does not internally update the icon. But when passing the data via options, the component is re-rendered with the new value provided in options.

VinitSarvade avatar Feb 07 '24 12:02 VinitSarvade

release 2.19.3 should fix an issue

JustFly1984 avatar Feb 12 '24 10:02 JustFly1984