Home > Back-end >  Geo Locate component in Leaflet React v3 - unwanted duplication on each refresh
Geo Locate component in Leaflet React v3 - unwanted duplication on each refresh

Time:04-02

I'm currently using Leaflet in React (v3) where you need to add components in order to render them on the map. This is the unwanted result output I am getting (green circles are duplicates and don't work on click either): Map Render Image

This keeps duplicating on each map interaction. I am not sure how to fix it and presume it is the library that is the issue as no other components replicate this behavior. If it can't be fixed, an alternative is welcome - as long it is compatible with leaflet-react v3. In short: - prevent duplicates on each map render. Geo locate user with permision in browser (on the first load, and then if the user pans away manually, to relocate/flyto with a button click)

import { useMap } from "react-leaflet";
import Locate from "leaflet.locatecontrol";
import "leaflet.locatecontrol/dist/L.Control.Locate.min.css";
import * as L from "leaflet";

const UserLocate = () => {
  const map = useMap();

  var lc = L.control
    .locate({
      position: "topright",
      strings: {
        title: "Show me where I am, yo!",
      },
    })
    .addTo(map);
  return null;
};

export default UserLocate;

/====================================================/

import EsriLeafletGeoSearch from "react-esri-leaflet/plugins/EsriLeafletGeoSearch";
import {
  MapContainer,
  Marker,
  TileLayer,
  Popup,
  ZoomControl,
  LayersControl,
  useMapEvents,
  useMapEvent,
  useMap,
} from "react-leaflet";

    import { Container, Button, Form, Row, Nav } from "react-bootstrap";
    import "leaflet/dist/leaflet.css";
    import "esri-leaflet-geocoder/dist/esri-leaflet-geocoder.css";
    import L from "leaflet";
    import { BiMapPin } from "react-icons/bi";
    import UserLocate from "./ProfilePage/UserLocate";


function GeneralMap() {
  const defaultZoom = 14;
        <MapContainer
          center={[48.856614, 2.3522219]}
          zoom={defaultZoom}
          style={{ height: 400, width: "100%" }}
        >
          <LayersControl>
            <BaseLayer checked name="Standard">
              <TileLayer
                attribution='"<a href=\"https://www.jawg.io\" target=\"_blank\">&copy; Jawg</a> - <a href=\"https://www.openstreetmap.org\" target=\"_blank\">&copy; OpenStreetMap</a>&nbsp;contributors"'
                url="https://{s}.tile.jawg.io/jawg-streets/{z}/{x}/{y}{r}.png?access-token="
              />
            </BaseLayer>
            <BaseLayer name="Black and White">
              <TileLayer
                attribution='"<a href=\"https://www.jawg.io\" target=\"_blank\">&copy; Jawg</a> - <a href=\"https://www.openstreetmap.org\" target=\"_blank\">&copy; OpenStreetMap</a>&nbsp;contributors"'
                url="https://{s}.tile.jawg.io/jawg-light/{z}/{x}/{y}{r}.png?access-token="
              />
            </BaseLayer>
          </LayersControl>
             <EsriLeafletGeoSearch
            position="topleft"
            useMapBounds={false}
            eventHandlers={{
              requeststart: () => console.log("Started request..."),
              requestend: () => console.log("Ended request..."),
              results: (r) => console.log(r),
            }}
          />
          <UserLocate />
        </MapContainer>

  );
}

export default GeneralMap;

CodePudding user response:

If you need to run code once, put it in useEffect like that:

useEffect(() => {
  //Code to run once
}, []);

  • Related