Search code examples
reactjsreact-google-mapsreact-google-maps-api

How to dynamically change icon on react-google-maps?


I would like that when clicked on a table, the icon on the map would be updated to another color. But the same does not happen. I don't know how to "refresh" the icon

import { GoogleMap, InfoWindow, useJsApiLoader, MarkerF } from "@react-google-maps/api";
import { options } from "../../../../../helpers/lib/MapOptions";
import { IDevice } from "pages/authenticated/DevicesAndAccessories/types";
import { useMapCenter } from "../../hooks/Index";
import { IDeviceReducer, IDeviceSelectedReducer } from "types/types";
import { useDispatch, useSelector } from "react-redux";
import { removeSelectedDevice, selectedDevice } from "redux/devices/actions";

const deaIcon: string =
require("../../../../../assets/icons/home-icons/Dea/dea.svg").default;
const deaSelected: string =
require("../../../../../assets/icons/home-icons/Dea/dea-selected.svg").default;

export const GoogleMapsPageMap = () =\> {
const dispatch = useDispatch();
const devicesData = useSelector((state: IDeviceReducer) =\> state.allDevices.devices);
const selectedDeviceData = useSelector((state: IDeviceSelectedReducer) =\> state.device);
const center = useMapCenter();

let { isLoaded } = useJsApiLoader({
id: "google-map-script",
googleMapsApiKey: "api_key",
});

return (
<\>
{isLoaded ? (
<GoogleMap
mapContainerStyle={{ width: "100%", height: "100%" }}
center={center}
zoom={15}
options={options}
>

          <MarkerF position={center}></MarkerF>
    
          {devicesData.map((item: IDevice, index: any) => (
            <MarkerF
              icon={deaIcon} // HERE IS THE PROBLEM
              key={item.id}
              position={devicesData[index].position}
              onClick={() => {
                dispatch(selectedDevice(item));
              }}
            >
              {selectedDeviceData.id === item.id &&
                <InfoWindow
                  position={devicesData[index].position}
                  onCloseClick={() => dispatch(removeSelectedDevice())}
                >
                  <div>{item.name}</div>
                </InfoWindow>
    
    
              }
            </MarkerF>
          ))}
    
        </GoogleMap>
      ) : null}
    </>

);
};

I tried using ternary, template string, but I don't know how to change the icon.


Solution

  • // ~ Dependencies
    import { GoogleMap, useJsApiLoader, MarkerF, OverlayView } from "@react-google-maps/api";
    // ~ State Management
    // ~ Services
    import { options } from "../../../../../helpers/lib/MapOptions";
    // ~ Hooks
    import { IDeviceReducer, IDeviceSelectedReducer, IUserReducer } from "types/types";
    import { useDispatch, useSelector } from "react-redux";
    import { removeSelectedDevice, selectedDevice } from "redux/devices/actions";
    import { InfoBoxStyled } from "./Index.styles";
    import { IDevice } from "types/globals";
    
    const deaIcon: string = require("../../../../../assets/icons/home-icons/Dea/dea-icon-map-not-selected.svg").default;
    const deaSelected: string = require("../../../../../assets/icons/home-icons/Dea/dea-selected.svg").default;
    
    export const GoogleMapsPageMap = () => {
      const dispatch = useDispatch();
      const devicesData = useSelector((state: IDeviceReducer) => state.allDevices.devices);
      const selectedDeviceData = useSelector((state: IDeviceSelectedReducer) => state.device);
      const userInfo: IUserReducer = useSelector((state: IUserReducer) => state);
    
      //   const center = {
      //     lat: userInfo.user.position.latitude,
      //     lng: userInfo.user.position.longitude
      // }
    
      const center = {
        lat: -30.058598,
        lng: -51.16944,
      };
    
      let { isLoaded } = useJsApiLoader({
        id: "google-map-script",
        googleMapsApiKey: "yoour_api_key",
      });
      const UserMarker: React.FC = () => {
        return <MarkerF position={center}></MarkerF>;
      };
      const DevicesMarkers: React.FC = () => {
        return (
          <>
            {devicesData.map((item: IDevice, index: number) => (
              <MarkerF
                icon={selectedDeviceData.id === item.id ? deaSelected : deaIcon}
                key={item.id}
                position={devicesData[index].position}
                onClick={() => {
                  dispatch(selectedDevice(item));
                }}
              >
                {selectedDeviceData.id === item.id && (
                  <OverlayView position={devicesData[index].position} mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}>
                    <InfoBoxStyled>{item.name}</InfoBoxStyled>
                  </OverlayView>
                )}
              </MarkerF>
            ))}
          </>
        );
      };
    
      return (
        <>
          {isLoaded ? (
            <GoogleMap mapContainerStyle={{ width: "100%", height: "100%" }} center={selectedDeviceData.position.lat === 0 ? center : selectedDeviceData.position} zoom={10} options={options}>
              <UserMarker />
              <DevicesMarkers />
            </GoogleMap>
          ) : null}
        </>
      );
    };