首页 > 解决方案 > React Leaflet:更新状态中多个标记的坐标

问题描述

我似乎无法弄清楚如何在将单个标记存储在状态后正确更新它们的坐标。目前它的工作原理是,当您单击地图上的某个位置时,它会添加一个标记并将其初始位置存储在状态中(在 markerData 中),然后通过地图函数显示在地图上。您可以移动各个标记,但我很难找出更新特定标记位置的可能解决方案,以便最终我可以在后端发送和存储标记信息。

这是我当前的代码。

import React, { Component } from 'react';
import { ImageOverlay, Map, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet/dist/leaflet.js';
import L from 'leaflet';

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
    iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
    iconUrl: require('leaflet/dist/images/marker-icon.png'),
    shadowUrl: require('leaflet/dist/images/marker-shadow.png')
});

export default class CustomMapExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      center: {
        lat: 512,
        lng: 1024,
      },
      zoom: 1,
      draggable: true,
      dimensions: [1024, 2048],
      markerData: [],
    };
  }

  toggleDraggable = () => {
    this.setState({ draggable: !this.state.draggable })
  }

  addMarker = (event) => {
    const {markerData} = this.state
    const coords = event.latlng
    markerData.push(coords)
    this.setState({markerData})
  }

  updateMarker = (event) => {
    console.log(event)
  }

  render () {
    const boundOrigin = [0, 0];
    const bounds = [boundOrigin, this.state.dimensions];
    const position = [this.state.center.lat, this.state.center.lng]

    return (
      <div>
        <Map
          id="map"
          crs={L.CRS.Simple}
          minZoom={-1}
          bounds={bounds}
          center={position}
          zoom={this.state.zoom}
          onClick={this.addMarker}
          >
          <ImageOverlay
            url='http://www.online-tabletop.com/wp-content/uploads/2017/01/tutoriala.jpg'
            bounds={bounds}
            />
          {this.state.markerData.map((element, index) =>
            <Marker
              key={index}
              position={element}
              draggable={this.state.draggable}
              onDragend={this.updateMarker}
              >
              <Popup>
                <span onClick={this.toggleDraggable}>
                  {this.state.draggable ? `Hello` : 'MARKER FIXED'}
                </span>
              </Popup>
            </Marker>
          )}
        </Map>
      </div>
    );
  }
}

标签: react-leaflet

解决方案


由于Marker接受选项对象作为第二个参数,因此可以引入标记索引来引用正在更新的标记:

<Marker
    key={index}
    marker_index={index}
    position={element}
    draggable={this.state.draggable}
    onDragend={this.updateMarker}
 />

And then markerData state could be updated like this once the marker is dragged:

updateMarker = event => {
   const latLng = event.target.getLatLng(); //get updated marker LatLng
   const markerIndex = event.target.options.marker_index; //get marker index
   //update 
   this.setState(prevState => {
     const markerData = [...prevState.markerData];
     markerData[markerIndex] = latLng;
     return { markerData: markerData };
   });
};

Demo


推荐阅读