react-google-maps-api
react-google-maps-api copied to clipboard
MarkerF does not update the marker color after modification
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 I am facing the same issue. Have you been able to find the solution for it?
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 😅
+1 to this issue.
Also experiencing this issue.
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
Amazing, this will work as a workaround, thank you @deivuss331 😁.
thanks a lot, you've saved my day! 😁 @deivuss331
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",
}}
/>
Thank you so much You save two life.. @VinitSarvade
@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
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 :)
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.
release 2.19.3 should fix an issue