React useCallback 函数在无限循环中运行
React useCallback function runs in infinite loop
我正在尝试使用 leaflet-geoman library in a React project. I need to create a custom toolbar button that enables and disables global drag mode。
单击工具栏按钮时,map.pm.enableGlobalDragMode();
函数启用全局模式。再次单击工具栏按钮时,map.pm.disableGlobalDragMode();
导致 useCallback 函数 afterClick
运行 无限循环。
useDraw.js
import React from "react";
const useDraw = (mapRef) => {
const afterClick = React.useCallback(() => {
console.log("afterclick");
const map = mapRef.current.leafletElement;
let editDragEnabled = false;
if (!editDragEnabled) {
console.log("enable");
map.pm.enableGlobalDragMode();
editDragEnabled = true;
} else {
console.log("disable");
map.pm.disableGlobalDragMode();
editDragEnabled = false;
}
}, [mapRef]);
React.useEffect(() => {
const map = mapRef.current.leafletElement;
var actions = ["finishMode"];
map.pm.addControls({
drawRectangle: false,
drawMarker: false,
drawPolyline: false,
drawPolygon: false,
drawCircle: false,
drawCircleMarker: false,
removalMode: false,
editMode: false,
cutPolygon: false,
dragMode: false
});
map.pm.Toolbar.createCustomControl({
name: "DragEdit",
block: "custom",
title: "Edit and Drag Layers",
onClick: () => afterClick(),
actions: actions,
toggle: true
});
}, [mapRef, afterClick]);
};
export default useDraw;
问题是,当enableGlobalDragMode
(或禁用)原始拖动按钮的控件被激活时,这将禁用您的自定义按钮(因为所有其他按钮都被禁用,因此只能使用一种模式活跃)。
我建议使用 enableGlobalDragMode
函数中的代码而不是调用它,这会导致控件发生变化:
const afterClick = React.useCallback(() => {
console.log("afterclick");
const map = mapRef.current.leafletElement;
const layers = L.PM.Utils.findLayers(map);
let dragMode = map.pm._customModeEnabled || false;
if(!dragMode){
console.log("enable");
layers.forEach((layer)=>{
layer.pm.enableLayerDrag();
})
}else{
console.log("disable");
layers.forEach((layer)=>{
layer.pm.disableLayerDrag();
})
}
map.pm._customModeEnabled = !dragMode;
}, [mapRef]);
我正在尝试使用 leaflet-geoman library in a React project. I need to create a custom toolbar button that enables and disables global drag mode。
单击工具栏按钮时,map.pm.enableGlobalDragMode();
函数启用全局模式。再次单击工具栏按钮时,map.pm.disableGlobalDragMode();
导致 useCallback 函数 afterClick
运行 无限循环。
useDraw.js
import React from "react";
const useDraw = (mapRef) => {
const afterClick = React.useCallback(() => {
console.log("afterclick");
const map = mapRef.current.leafletElement;
let editDragEnabled = false;
if (!editDragEnabled) {
console.log("enable");
map.pm.enableGlobalDragMode();
editDragEnabled = true;
} else {
console.log("disable");
map.pm.disableGlobalDragMode();
editDragEnabled = false;
}
}, [mapRef]);
React.useEffect(() => {
const map = mapRef.current.leafletElement;
var actions = ["finishMode"];
map.pm.addControls({
drawRectangle: false,
drawMarker: false,
drawPolyline: false,
drawPolygon: false,
drawCircle: false,
drawCircleMarker: false,
removalMode: false,
editMode: false,
cutPolygon: false,
dragMode: false
});
map.pm.Toolbar.createCustomControl({
name: "DragEdit",
block: "custom",
title: "Edit and Drag Layers",
onClick: () => afterClick(),
actions: actions,
toggle: true
});
}, [mapRef, afterClick]);
};
export default useDraw;
问题是,当enableGlobalDragMode
(或禁用)原始拖动按钮的控件被激活时,这将禁用您的自定义按钮(因为所有其他按钮都被禁用,因此只能使用一种模式活跃)。
我建议使用 enableGlobalDragMode
函数中的代码而不是调用它,这会导致控件发生变化:
const afterClick = React.useCallback(() => {
console.log("afterclick");
const map = mapRef.current.leafletElement;
const layers = L.PM.Utils.findLayers(map);
let dragMode = map.pm._customModeEnabled || false;
if(!dragMode){
console.log("enable");
layers.forEach((layer)=>{
layer.pm.enableLayerDrag();
})
}else{
console.log("disable");
layers.forEach((layer)=>{
layer.pm.disableLayerDrag();
})
}
map.pm._customModeEnabled = !dragMode;
}, [mapRef]);