Fix Leaflet map initialization: prevent DOM errors and ensure robust container checks
- Refactored initializeMap to accept the DOM node instead of the ref object - Updated all checks to use the DOM node directly - Improved useInitializeMap to only call initializeMap when the container is ready - Prevents "mapRef.current ist nicht definiert oder nicht im DOM" errors - Ensures map is only initialized when the container is attached
This commit is contained in:
@@ -206,6 +206,16 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}
|
||||
};
|
||||
//-----------------------------Map Initialisierung----------------
|
||||
// Default map options for Leaflet
|
||||
const mapOptions = {
|
||||
center: currentCenter,
|
||||
zoom: currentZoom,
|
||||
zoomControl: true,
|
||||
contextmenu: true,
|
||||
contextmenuWidth: 180,
|
||||
contextmenuItems: [],
|
||||
};
|
||||
|
||||
useInitializeMap(
|
||||
map,
|
||||
mapRef,
|
||||
@@ -214,7 +224,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
setMenuItemAdded,
|
||||
addItemsToMapContextMenu,
|
||||
hasRights,
|
||||
value => dispatch(setDisabled(value))
|
||||
value => dispatch(setDisabled(value)),
|
||||
mapOptions // pass mapOptions
|
||||
);
|
||||
|
||||
//-------------------------React Hooks--------------------------------
|
||||
|
||||
@@ -2,12 +2,58 @@
|
||||
import { useEffect } from "react";
|
||||
import { initializeMap } from "../../../utils/initializeMap";
|
||||
|
||||
const useInitializeMap = (map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled) => {
|
||||
const useInitializeMap = (
|
||||
map,
|
||||
mapRef,
|
||||
setMap,
|
||||
setOms,
|
||||
setMenuItemAdded,
|
||||
addItemsToMapContextMenu,
|
||||
hasRights,
|
||||
setPolylineEventsDisabled,
|
||||
mapOptions
|
||||
) => {
|
||||
useEffect(() => {
|
||||
if (mapRef.current && !map) {
|
||||
initializeMap(mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled);
|
||||
let cancelled = false;
|
||||
function tryInit(firstAttempt = true) {
|
||||
if (cancelled) return;
|
||||
// Only try to initialize if mapRef.current is ready and in DOM
|
||||
if (
|
||||
mapRef.current &&
|
||||
mapRef.current instanceof HTMLElement &&
|
||||
document.body.contains(mapRef.current) &&
|
||||
!map &&
|
||||
!mapRef.current._leaflet_id
|
||||
) {
|
||||
try {
|
||||
const result = initializeMap(
|
||||
mapRef.current, // pass DOM node, not ref
|
||||
setMenuItemAdded,
|
||||
addItemsToMapContextMenu,
|
||||
hasRights,
|
||||
setPolylineEventsDisabled,
|
||||
firstAttempt // log error only on first real attempt
|
||||
);
|
||||
if (result && result.map && result.oms) {
|
||||
setMap(result.map);
|
||||
setOms(result.oms);
|
||||
}
|
||||
} catch (error) {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Map initialization error:", error);
|
||||
}
|
||||
}
|
||||
} else if (!map && !cancelled) {
|
||||
// If not ready, just retry after a short delay, do not call initializeMap at all
|
||||
setTimeout(() => tryInit(false), 50);
|
||||
}
|
||||
}
|
||||
}, [mapRef, map, hasRights, setPolylineEventsDisabled]);
|
||||
tryInit(true);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [mapRef, map, hasRights, setPolylineEventsDisabled, mapOptions]);
|
||||
};
|
||||
|
||||
export default useInitializeMap;
|
||||
|
||||
Reference in New Issue
Block a user