Skip to content

Markers are Flikering in React #1197

Description

@Gabriel-Mios

I have a problem with the markers and its consistently flickering and i dont know whats going on
here is the code
`import React, { useEffect, useMemo, useState } from "react";
import "../Map/map.css";
import {
GoogleMap,
LoadScript,
GoogleMapProps,
MarkerF,
Marker,
} from "@react-google-maps/api";
import { DeliverymanService, RestaurantsService } from "kauai-super-app-client-module/client-web";
import { useCoordsContext } from "../../context/coordsContext";

const Map = () => {
const refMap = React.useRef(null);

const [map, setMap] = React.useState(null);
const [mapKey, setMapKey] = useState(new Date().getTime());
const [markers, setMarkers] = useState([]);
const [markersRestaurant, setMarkersRestaurant] = useState([]);

const { coords, addCoords } = useCoordsContext();

const position = useMemo(() => ({ lat: -11.857491, lng: -55.50621 }), []);
const containerStyle = {
width: "98%",
height: "100%",
marginLeft: "5px",
};

useEffect(() => {
if (coords != null) {
try {
if (map && markers.length > 0) {
const bounds = new window.google.maps.LatLngBounds();
bounds.extend(coords);
map.fitBounds(bounds);
const maxZoom = map.getZoom();
map.setZoom(14);
}
} catch (error) {
console.log(error);
}
}
}, [coords]);

useEffect(() => {
DeliverymanService.getAllDeliveryman()
.then((response) => {
const simplifiedItems = response.data.map((item) => ({
id: item._id.$oid,
name: item.name,
position: {
lat: parseFloat(item.current_location.latitude),
lng: parseFloat(item.current_location.longitude),
},
}));
setMarkers(...markers, simplifiedItems);
})
.catch((error) => {
console.log(error);
});

RestaurantsService.returnAllRestaurants().then((response) => {
  const simplifiedItems = response.data.map((item) => ({
    id: item._id.$oid,
    name: item.name,
    position: {
      lat: parseFloat(item.latitude),
      lng: parseFloat(item.longitude),
    },
  }));
  setMarkersRestaurant(...markersRestaurant, simplifiedItems);
}).catch((error) => {
  console.log(error);
});

setInterval(() => {
  DeliverymanService.getAllDeliveryman()
    .then((response) => {
      const simplifiedItems = response.data.map((item) => ({
        id: item._id.$oid,
        name: item.name,
        position: {
          lat: parseFloat(item.current_location.latitude),
          lng: parseFloat(item.current_location.longitude),
        },
      }));
      setMarkers(...markers, simplifiedItems);
    })
    .catch((error) => {
      console.log(error);
    });
  RestaurantsService.returnAllRestaurants().then((response) => {
    const simplifiedItems = response.data.map((item) => ({
      id: item._id.$oid,
      name: item.name,
      position: {
        lat: parseFloat(item.latitude),
        lng: parseFloat(item.longitude),
      },
    }));
    setMarkersRestaurant(...markersRestaurant, simplifiedItems);
  }).catch((error) => {
    console.log(error);
  });
}, 3000);

}, []);

const onUnmount = React.useCallback(function callback() {
// setMap(null);
}, []);

function MarkerDelivery() {
return (
<>
{markers.map((value) => {
return (
<>
<Marker
key={String(value.id)}
position={{ lat: value.position.lat, lng: value.position.lng }}
options={{
optimized: true,
visible: true,
label: {
text: value?.name === undefined ? "Não identificado" : value?.name,
className: "marker-label",
}
}}
icon={{
url: "https://bohocasasstorage.blob.core.windows.net/boho-casas/pin_delivery.png",
scaledSize: new window.google.maps.Size(70, 80),
}}
/>
</>
);
})}
</>
);
}

function MarkerRestaurant() {
return (
<>
{markersRestaurant.map((value) => {
return (
<>
<Marker
key={String(value.id)}
position={{ lat: value.position.lat, lng: value.position.lng }}
options={{
optimized: true,
visible: true,
label: {
text: value?.name === undefined ? "Não identificado" : value?.name,
className: "marker-label",
}
}}
icon={{
url: "https://bohocasasstorage.blob.core.windows.net/boho-casas/pin_restaurant.png",
scaledSize: new window.google.maps.Size(70, 80),
}}
/>
</>
);
})}
</>
);
}

function FitToMarkersDeliveryMans() {
try {
if (map && markers.length > 0) {
const bounds = new window.google.maps.LatLngBounds();

    markers.forEach((marker) => {
      bounds.extend(marker.position);
    });

    map.fitBounds(bounds);
    console.log(bounds.Ia.hi);
    console.log(bounds.Ia.lo);
  }
} catch (error) {
  console.error(error);
}

}

function FitToMarkersRestaurants() {
try {
if (map && markers.length > 0) {
const bounds = new window.google.maps.LatLngBounds();

    var cpMarkers = Object.assign([], markers);
    cpMarkers.push(...markersRestaurant);

    cpMarkers.forEach((marker) => {
      bounds.extend(marker.position);
    });

    map.fitBounds(bounds);
    console.log(bounds.Ia.hi);
    console.log(bounds.Ia.lo);
  }
} catch (error) {
  console.error(error);
}

}

return (
<>

<GoogleMap
mapContainerStyle={containerStyle}
center={position}
zoom={14}
key={mapKey}
ref={refMap}
streetView={false}
options={{
streetViewControl: false,
// mapTypeId: "satellite",
}}
onLoad={(mapdata) => {
setMap(mapdata);
}}
onUnmount={onUnmount}
>
{markers.length > 0 && (
<>


</>
)}
{




Kauai

          <div className="custom-tools">
            <button
              onClick={FitToMarkersDeliveryMans}
              className="buttom-custom-tools"
            >
              Todos Motoboys
            </button>
          </div>

        </div>
      }
    </GoogleMap>
  </LoadScript>
</>

);
};

export default Map;
`
here is the video demonstrating whats going on
screen-capture (8).webm

Activity

  1. bguillozet commented on Sep 21, 2023

    @bguillozet
  2. HelloNeptune commented on Oct 25, 2023

    @HelloNeptune

    I found a workaround until this issue get resolved;

    with react 18 you can use createRoot method from 'react-dom/client' module so, in the onGoogleApiLoaded callback it is possible to render your custom marker into the map dynamically;

    import { createRoot } from 'react-dom/client';
    ...
    
    const HQMarkerTemplate: React.FC = () => (
      <>
       <div>Test Marker</div>
      </>
    );
    
    export const MapHandler = () => {
      const handleApiLoaded = (map: GoogleMapReact, maps: any) => {
        const HQMarker = function (lat, lng) {
            this.lat = lat;
            this.lng = lng;
            this.pos = new maps.LatLng(lat, lng);
        };
    
        HQMarker.prototype = new maps.OverlayView();
        HQMarker.prototype.onAdd = function () {
    
          // here is the solution -->
          const container = document.createElement('span');
          const root = createRoot(container);
          root.render(<HQMarkerTemplate />);
    
          const panes = this.getPanes();
          panes.overlayImage.appendChild(container);
        };
    
        HQMarker.prototype.draw = function () {
          var overlayProjection = this.getProjection();
          var position = overlayProjection.fromLatLngToDivPixel(this.pos);
          var panes = this.getPanes();
          panes.overlayImage.style.left = position.x + "px";
          panes.overlayImage.style.top = position.y - 20 + "px";
        };
    
        new HQMarker(endPoint.lat, endPoint.lng).setMap(map);
      };
    
        ...
        ...
        ...
    
    
      return (
        <GoogleMapReact
            yesIWantToUseGoogleMapApiInternals
            onGoogleApiLoaded={({ map, maps }) => handleApiLoaded(map, maps)}
            options={...}
        />
      )
    }
  3. tragicmj commented on Dec 12, 2023

    @tragicmj

    @HelloNeptune from where is endPoint coming?

  4. HelloNeptune commented on Dec 12, 2023

    @HelloNeptune

    @HelloNeptune from where is endPoint coming?

    Its just an object which contains lat and lng fields

  5. tragicmj commented on Dec 12, 2023

    @tragicmj

    @HelloNeptune from where is endPoint coming?

    Its just an object which contains lat and lng fields

    I do understand that but it not defined anywhere else, it is throwing error at my end, endPoint is undefined

  6. HelloNeptune commented on Dec 12, 2023

    @HelloNeptune

    @HelloNeptune from where is endPoint coming?

    Its just an object which contains lat and lng fields

    I do understand that but it not defined anywhere else, it is throwing error at my end, endPoint is undefined

    You can use your own values 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions