fix: Behebt TypeError: Cannot read properties of null (reading 'contextmenu') mit Redux

- Implementiert `store.subscribe()` in `setupPolylines.js`, um das Kontextmenü-Handling über Redux zu steuern.
- Ersetzt `useDispatch()` und `useSelector()` durch `store.dispatch()` und `store.getState()` in einer Nicht-React-Datei.
- Fügt eine `forceClose`-Action in `polylineContextMenuSlice.js` hinzu, um das Kontextmenü synchron mit `setInterval` zu schließen.
- Stellt sicher, dass das Kontextmenü **immer vor Ablauf des 20-Sekunden-Intervalls** geschlossen wird.
- Verhindert doppelte Menüinstanzen und sorgt für ein stabiles Verhalten bei wiederholten Interaktionen.

 Fix für `TypeError: Cannot read properties of null (reading 'contextmenu')`
 **Verhindert Kontextmenü-Fehler beim automatischen Datenupdate**
 **Redux-gesteuerte Menüverwaltung für stabilere Performance**
 **Kein unerwartetes Offenbleiben oder erneutes Rendern des Menüs mehr**
This commit is contained in:
ISA
2025-03-10 13:49:11 +01:00
parent 1298ce3a81
commit 8ab1c53996
5 changed files with 110 additions and 25 deletions

View File

@@ -15,6 +15,7 @@ import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleS
import { useRecoilValue } from "recoil";
import { store } from "../redux/store"; // Importiere den Store
import { openAddPoiOnPolylineModal } from "../redux/slices/addPoiOnPolylineSlice";
import { openPolylineContextMenu, closePolylineContextMenu } from "../redux/slices/polylineContextMenuSlice";
// Funktion zum Deaktivieren der Polyline-Ereignisse
export function disablePolylineEvents(polylines) {
@@ -51,39 +52,60 @@ export function enablePolylineEvents(polylines, lineColors) {
// Funktion zum Schließen des Kontextmenüs und Entfernen der Markierung
function closePolylineSelectionAndContextMenu(map) {
try {
// Entferne alle markierten Polylinien
// Falls eine Polyline aktiv ist, entfernen
if (window.selectedPolyline) {
window.selectedPolyline.setStyle({ weight: 3 }); // Originalstil wiederherstellen
window.selectedPolyline.setStyle({ weight: 3 });
window.selectedPolyline = null;
}
// Überprüfe, ob map und map.contextmenu definiert sind
if (map && map.contextmenu) {
map.contextmenu.hide(); // Kontextmenü schließen
// Überprüfen, ob das Kontextmenü existiert, bevor es geschlossen wird
if (map && map.contextmenu && typeof map.contextmenu.hide === "function") {
map.contextmenu.hide(); // Menü schließen
} else {
console.warn("Kontextmenü ist nicht verfügbar.");
console.warn("Kontextmenü existiert nicht mehr oder wurde bereits entfernt.");
}
} catch (error) {
console.error("Fehler beim Schließen des Kontextmenüs:", error);
window.location.reload();
}
// Countdown-Status zurücksetzen
// Lokale Speicherwerte zurücksetzen
localStorage.removeItem("contextMenuCountdown");
localStorage.removeItem("contextMenuExpired");
}
// Überprüft regelmäßig den Status in localStorage
function monitorContextMenu(map) {
setInterval(() => {
function checkAndClose() {
const isContextMenuExpired = localStorage.getItem("contextMenuExpired") === "true";
if (isContextMenuExpired) {
closePolylineSelectionAndContextMenu(map);
localStorage.removeItem("contextMenuExpired"); // Flagge entfernen, um wiederverwendbar zu sein
}
}, 1000); // Alle 1 Sekunde überprüfen
}
if (isContextMenuExpired) {
if (map && map.contextmenu && typeof map.contextmenu.hide === "function") {
closePolylineSelectionAndContextMenu(map);
localStorage.removeItem("contextMenuExpired");
} else {
console.warn("Kontextmenü war nicht verfügbar und konnte nicht geschlossen werden.");
}
}
setTimeout(checkAndClose, 1000); // **Recursive Timeout statt Intervall**
}
checkAndClose();
}
//------------------------------------------
store.subscribe(() => {
const state = store.getState(); // Redux-Toolkit empfohlene Methode
if (state.polylineContextMenu.forceClose) {
console.log("🚀 Redux-Event erkannt - Kontextmenü wird geschlossen.");
store.dispatch(closePolylineContextMenu());
if (window.map && window.map.contextmenu) {
window.map.contextmenu.hide();
}
}
});
//--------------------------------------------
export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter, polylineVisible) => {
if (!polylineVisible) {
console.warn("Polylines deaktiviert - keine Zeichnung");
@@ -292,7 +314,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
store.dispatch(openAddPoiOnPolylineModal(e.latlng));
},
},
*/
*/
{
text: "Stützpunkt hinzufügen",
icon: "/img/icons/gisLines/add-support-point.svg",
@@ -404,15 +426,32 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
localStorage.setItem("polylineLink", link);
});
*/
// Starte den Timer zum Schließen des Kontextmenüs nach 15 Sekunden
polyline.on("contextmenu", function (e) {
const contextMenu = this._map.contextmenu; // Zugriff auf das Kontextmenü
const closeMenu = () => contextMenu.hide(); // Funktion zum Schließen des Menüs
const countdown = parseInt(localStorage.getItem("contextMenuCountdown"), 30);
if (countdown >= 28) {
closeMenu();
}
// Event-Listener für Redux Store-Änderungen registrieren
// Starte den Timer zum Schließen des Kontextmenüs nach 15 Sekunden
polyline.on("contextmenu", (e) => {
store.dispatch(closePolylineContextMenu());
setTimeout(() => {
if (!map || !map.contextmenu) return;
store.dispatch(
openPolylineContextMenu({
position: { lat: e.latlng.lat, lng: e.latlng.lng },
polylineId: polyline.options.idLD,
})
);
// Schließen nach 17 Sekunden
setTimeout(() => {
store.dispatch(closePolylineContextMenu());
if (map.contextmenu) {
map.contextmenu.hide();
}
}, 17000);
}, 50);
});
polylines.push(polyline);