【问题标题】:React useCallback function runs in infinite loopReact useCallback 函数无限循环运行
【发布时间】:2021-01-26 09:54:52
【问题描述】:

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

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

codesandbox.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;

【问题讨论】:

  • 为什么要创建一个新的拖动按钮而不是覆盖现有的?你想定制什么?
  • @FalkeDesign 启用/禁用一起拖动和编辑所有几何图形

标签: reactjs react-hooks leaflet react-leaflet leaflet-geoman


【解决方案1】:

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

【讨论】:

  • 谢谢,我要去看看。
  • 我正在尝试使用这种方法实现将所有多边形一起拖动,但似乎来自 pmDrag 子插件的pmDrag.setMode(1); 不起作用。你能看看我的codesandbox吗?
猜你喜欢
  • 2021-05-23
  • 1970-01-01
  • 2021-01-14
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 2021-08-28
  • 2020-07-18
相关资源
最近更新 更多