微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React useCallback 函数在无限循环中运行

如何解决React useCallback 函数在无限循环中运行

我正在尝试在 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;

解决方法

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。