首页 > 解决方案 > React Leaflet:有没有办法制作一个添加标记并使用该标记位置更新状态的 onClick 方法?(初学者反应)

问题描述

我已经看到他们使用 Map 组件的解决方案,但我读到这已更新为没有 onClick 方法的 MapContainer。现在,我的代码(如下)允许我在单击地图上的任意位置时添加标记。正如我的标题所述,我将如何将新标记存储在某种可用变量中。我的最终目标是在 MongoDB 中存储新的标记。提前致谢。

import React, { Component } from 'react';
import {
  MapContainer,
  TileLayer,
  MapConsumer,
} from "react-leaflet";
import Leaflet from "leaflet";
import { connect } from 'react-redux';

import { Icon } from "../Leaflet/Configurations";
import NavBar from '../components/NavBar';
import Footer from '../components/Footer';
import { registerHouse } from '../actions/houseActions';
import { clearErrors } from "../actions/errorActions";
import "leaflet/dist/leaflet.css";

class MyMap extends Component{
    constructor(props){
        super(props);
        this.state = {
            markers: [[40.7, -74]],
            data: []
        };
        this.addMarker = this.addMarker.bind(this);
    }
    
    render(){
        return(
            <div>
                <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
   integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
   crossOrigin=""/>
                <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
            integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
            crossOrigin=""></script>
                <NavBar/>
                {/* <MapContainer className="Map" center={{ lat: 40.7 , lng: -74 }} zoom={15} scrollWheelZoom={false}>
                    <TileLayer
                        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                    />
                    <MapConsumer>
                        {(map) => {
                            console.log("map center:", map.getCenter());
                            map.on("click", function (e) {
                                const { lat, lng } = e.latlng;
                                Leaflet.marker([lat, lng], { Icon }).addTo(map);
                                let tmp = this.state.data;
                                tmp.append([lat,lng]);
                                this.setState({data:tmp});
                            });
                            return null;
                        }}
                    </MapConsumer>
                </MapContainer> */}
                <Footer/>
            </div>
        )
    }
}


const mapStateToProps =  state => ({
    isAuthenticated: state.auth.isAuthenticated,
    error: state.error
});

export default connect(mapStateToProps, { registerHouse, clearErrors })(MyMap);

标签: javascriptreactjsleafletreact-leaflet

解决方案


我不确定您的这部分代码是否有效:

let tmp = this.state.data;
tmp.append([lat,lng]);
this.setState({data:tmp});

为什么?因为在块范围内this.state未定义。map.on('click)它在那里失去了参考。

所以你可以做的是创建一个 MapContainer 的自定义子组件,并利用 react 中的一个概念,称为从子组件向父组件引发事件。父母将向孩子发送一个事件,孩子在发生事情时调用该函数。

function MyComponent({ saveMarkers }) {
  const map = useMapEvents({
    click: (e) => {
      const { lat, lng } = e.latlng;
      L.marker([lat, lng], { icon }).addTo(map);
      saveMarkers([lat, lng]);
    }
  });
  return null;
}

并在您的 MyMap comp 中定义事件

saveMarkers = (newMarkerCoords) => {
    const data = [...this.state.data, newMarkerCoords];
    this.setState((prevState) => ({ ...prevState, data }));
};

它将作为道具传递给自定义组合:

 <MapContainer
   ...
  <MyComponent saveMarkers={this.saveMarkers} />
 </MapContainer>

演示


推荐阅读