首页 > 解决方案 > React useCallback 函数无限循环运行

问题描述

我正在尝试在 React 项目中使用Leaflet-geoman库。我需要创建一个自定义工具栏按钮来启用和禁用全局拖动模式

单击工具栏按钮时,map.pm.enableGlobalDragMode();函数启用全局模式。再次单击工具栏按钮时,map.pm.disableGlobalDragMode();会导致 useCallback 函数afterClick无限循环运行。

码沙盒.io

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;

标签: reactjsreact-hooksleafletreact-leafletleaflet-geoman

解决方案


问题是,当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]);

推荐阅读