如何在运行时更改 react-google-maps <DrawingManager> 组件道具 drawingMode 道具而不更改组件状态

how can I change react-google-maps <DrawingManager> component prop drawingMode props in runtime without change component state

我在我的 React 项目中使用了 react-google-maps 库。我希望在完成绘制形状后,用户无法再绘制并且形状停留在屏幕上。

我有流式片段:

<GoogleMap
  zoom={16}
  center={initialPosition}
  mapTypeId="satellite"
>
  <DrawingManager
    drawingMode={"polygon"}
    onPolygonComplete={onDrawComplete}
  />
</GoogleMap>

使用此代码,用户可以绘制他想要的任何形状以及他想要的形状数量。 我看到我可以将 componente 的 drawingMode 更改为 null。 我试图将此值存储在组件状态中,但是当我尝试在 onDrawComplete() 回调中更改此值时,地图会重新呈现,我不希望出现这种行为。 问题:如何在不使用组件状态的情况下将此 prop 更改为 null?

您可以通过以下步骤实现:

  1. 从库中导入对象:
import {
  withGoogleMap,
  GoogleMap,
  Marker,
  Polyline,
  Circle,
  Rectangle,
  Polygon
} from "react-google-maps";
import { DrawingManager } from "react-google-maps/lib/components/drawing/DrawingManager";
  1. 为每个覆盖声明不同的状态变量。这些将是您在创建这些不同的覆盖对象时需要的变量。您还应该有一个变量 drawingControlEnabled 来设置绘图管理器的 options>drawingControl 参数的值。
this.state = {
      drawingControlEnabled: true,
      marker: null,
      polyline: null,
      circleRadius: null,
      circleCenter: null,
      rectangle: null,
      polygon: null,
      visible: true
    };
  1. 使用带有 onOverlayComplete 参数的绘图管理器,它将转到一个函数,该函数将在您每次绘制完叠加层时进行监听。
<DrawingManager
          onOverlayComplete={this.overlay}
          defaultOptions={{
            drawingControlOptions: {
              position: google.maps.ControlPosition.TOP_CENTER,
              drawingModes: [
                google.maps.drawing.OverlayType.CIRCLE,
                google.maps.drawing.OverlayType.POLYGON,
                google.maps.drawing.OverlayType.POLYLINE,
                google.maps.drawing.OverlayType.RECTANGLE
              ]
            }
          }}
          options={{
            drawingControl: this.state.drawingControlEnabled
          }}
        />
  1. 在onOverlayComplete函数中,您应该将drawingControlEnabled状态设置为false。这将在绘制叠加层后删除绘图控件。您还应该有一个开关盒,可以检查您制作的覆盖层的情况。对于每个条件,从每个覆盖类型的 event.overlay 中获取值,并在状态变量中传递每个覆盖类型所需参数的值。
  overlay = e => {
    this.setState({
      drawingControlEnabled: false
    });
    console.log(e);
    switch (e.type) {
      case "marker":
        this.setState({
          marker: {
            lat: e.overlay.getPosition().lat(),
            lng: e.overlay.getPosition().lng()
          }
        });
        break;
      case "polyline":
        this.setState({
          polyline: e.overlay.getPath()
        });
        break;
      case "circle":
        this.setState({
          circleRadius: e.overlay.getRadius(),
          circleCenter: e.overlay.getCenter()
        });
        break;
      case "rectangle":
        this.setState({
          rectangle: e.overlay.getBounds()
        });

        break;
      case "polygon":
        this.setState({
          polygon: e.overlay.getPaths()
        });
        break;
    }
  };
  1. 在对象内部的 render() 区域中,添加不同的覆盖对象,条件是检查该对象的状态变量是否不为空。这样做只会在状态变量具有上述 switch 情况下的值时才显示对象。
{this.state.marker !== null && <Marker position={this.state.marker} />}

        {this.state.polyline !== null && (
          <Polyline path={this.state.polyline} />
        )}
        {this.state.circleRadius !== null && (
          <Circle
            radius={this.state.circleRadius}
            center={this.state.circleCenter}
            visible={this.state.visible}
          />
        )}

        {this.state.rectangle !== null && (
          <Rectangle bounds={this.state.rectangle} />
        )}
        {this.state.polygon !== null && <Polygon paths={this.state.polygon} />}

这里是working code sample。注意:将您的 API 密钥放入 index.js 以使其正常工作。

TLDR:您需要捕获 drawingManager 引用并使用它做所有事情。

Google 地图和其他 Google 东西就像一个平行世界(如果我可以这么说的话)。您需要直接使用他们的实例来做所有事情。

google.maps.events.addEventListener google.maps.events.addDOMListener ...等等...

在 React 中,我无法找到一种不同的方法:

  1. 使用onLoad事件到达drawingManager实例

    <DrawingManager onLoad={handlerLoadDrawingManager} ...other />
    
  2. 创建引用并分配 handlerLoadDrawingManager

    中引用的 drawingManagerInstance
    const drawingManager = useRef()
    
    const handlerLoadDrawingManager = (drawingManagerInstance) => {
        drawingManager.current = drawingManagerInstance
    }
    
  3. 使用drawingManager.current.setDrawingMode(<some mode>)

    const someFunction = () => drawingManager.current.setDrawingMode(google.maps.drawing.OverlayType.POLYGON)
    

    更多模式见drawing manager overlay types

PDT:对地图实例、多边形以及您需要与之交互的其他地图对象执行相同操作