5

I have a custom theme in my website (light/dark) and I have a custom hook for that also. I put google map (react-google-maps) custom style in a useMemo and set theme as the dependancy but when I change theme it seems that map component doesn't re-render and apply new colors.. I tried to debug but no luck. here's my implementation:

export const MapMarkerSelection = compose(
    withProps({
        googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${API_KEY_MAP}&libraries=geometry,drawing,places`,
        loadingElement: <div style={{height: `100%`}} />,
        containerElement: (
            <div style={{height: `400px`, margin: `8px 0 20px`, borderRadius: `0.5rem`, overflow: 'hidden'}} />
        ),
        mapElement: <div style={{height: `100%`}} />,
    }),
    withScriptjs,
    withGoogleMap,
)((props) => {
    const mapRef = useRef();
    const theme = useTheme(); //here is mu custom hook (no issue with this it work fine in other components)

    useEffect(() => {
        setLatMarker(props.markerPosition.latitude);
        setLngMarker(props.markerPosition.longitude);
        mapRef.current.panTo({
            lat: props.markerPosition.latitude,
            lng: props.markerPosition.longitude,
        });
    }, [props.markerPosition, props.markerPosition.latitude, props.markerPosition.longitude]);

    const [latMarker, setLatMarker] = useState(props.markerPosition.latitude);
    const [lngMarker, setLngMarker] = useState(props.markerPosition.longitude);
    const setCallback = useCallback(
        (latLng) => {
            if (props.onSelectPosition) {
                props.onSelectPosition({latitude: latLng.lat(), longitude: latLng.lng()});
                setLatMarker(latLng.lat());
                setLngMarker(latLng.lng());
                mapRef.current.panTo({
                    lat: latLng.lat(),
                    lng: latLng.lng(),
                });
            }
        },
        [props],
    );

    const mapStyle = useMemo(() => {
        console.log('here');
        return [
            {
                featureType: 'water',
                elementType: 'geometry',
                stylers: [
                    {
                        color: theme.BACKGROUND_COLOR, //here I set water color to dark for dark theme and blue for lighr theme
                    },
                    {
                        lightness: 17,
                    },
                ],
            },
            {
                featureType: 'landscape',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5',
                    },
                    {
                        lightness: 20,
                    },
                ],
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#ffffff',
                    },
                    {
                        lightness: 17,
                    },
                ],
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#ffffff',
                    },
                    {
                        lightness: 29,
                    },
                    {
                        weight: 0.2,
                    },
                ],
            },
            {
                featureType: 'road.arterial',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff',
                    },
                    {
                        lightness: 18,
                    },
                ],
            },
            {
                featureType: 'road.local',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff',
                    },
                    {
                        lightness: 16,
                    },
                ],
            },
            {
                featureType: 'poi',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5',
                    },
                    {
                        lightness: 21,
                    },
                ],
            },
            {
                featureType: 'poi.park',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#dedede',
                    },
                    {
                        lightness: 21,
                    },
                ],
            },
            {
                elementType: 'labels.text.stroke',
                stylers: [
                    {
                        visibility: 'on',
                    },
                    {
                        color: '#ffffff',
                    },
                    {
                        lightness: 16,
                    },
                ],
            },
            {
                elementType: 'labels.text.fill',
                stylers: [
                    {
                        saturation: 36,
                    },
                    {
                        color: '#333333',
                    },
                    {
                        lightness: 40,
                    },
                ],
            },
            {
                elementType: 'labels.icon',
                stylers: [
                    {
                        visibility: 'off',
                    },
                ],
            },
            {
                featureType: 'transit',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f2f2f2',
                    },
                    {
                        lightness: 19,
                    },
                ],
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#fefefe',
                    },
                    {
                        lightness: 20,
                    },
                ],
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#fefefe',
                    },
                    {
                        lightness: 17,
                    },
                    {
                        weight: 1.2,
                    },
                ],
            },
        ];
    }, [theme.BACKGROUND_COLOR]);

    return (
        <GoogleMap
            ref={mapRef}
            defaultOptions={{
                styles: mapStyle,
            }}
            defaultZoom={12}
            defaultCenter={{lat: latMarker, lng: lngMarker}}
            onClick={({latLng}) => setCallback(latLng)}
        >
            <Marker position={{lat: latMarker, lng: lngMarker}} draggable onDragEnd={({latLng}) => setCallback(latLng)} />
        </GoogleMap>
    );
});

only if I refresh the page the new theme for map applies. how can I solve this?

EshgheCode
  • 288
  • 4
  • 19

1 Answers1

0

Does theme change constantly? If not, just add a key to GoogleMap, keep in mind this will cause a full rerender of the map, maybe not what you want if the user can move the map around.

Also, check the documentation for the library, or post it here if possible, it may be that the defaultOptions prop is internally cached by the component to prevent rerenders. Also, when using memo, avoid stuff like prop={{memoizedValue}} since your're still creating a new object everytime, intead go for prop={memoizedValue}.

<GoogleMap
  ...
  key={theme.BACKGROUND_COLOR}
/>
Arthur Bruel
  • 678
  • 3
  • 12
  • I say you should check the documentation because sometimes, components which reference as prop as `default` something, usually cache that prop and make internal changes to it, ignoring updates. **The same thing that happens with uncontrolled** ` – Arthur Bruel Nov 30 '21 at 16:53