React Leaflet:有没有办法制作一个添加标记并使用该标记位置更新状态的 onClick 方法? (初学者反应)
React Leaflet: Is there a way to make an onClick method that adds a marker and also updates the state with that markers' location? (Beginner React)
我看到他们使用 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='© <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);
我不确定这部分代码是否有效:
let tmp = this.state.data;
tmp.append([lat,lng]);
this.setState({data:tmp});
为什么?因为 this.state
在 map.on('click)
块范围内未定义。它在那里失去了参考。
因此,您可以做的是创建 MapContainer 的自定义 child 组件,并利用 React 中的一个概念,称为将事件从 child 引发到 parent 组件。 parent 将向 child 发送一个事件,后者在发生某些事情时调用该函数。
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>
我看到他们使用 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='© <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);
我不确定这部分代码是否有效:
let tmp = this.state.data;
tmp.append([lat,lng]);
this.setState({data:tmp});
为什么?因为 this.state
在 map.on('click)
块范围内未定义。它在那里失去了参考。
因此,您可以做的是创建 MapContainer 的自定义 child 组件,并利用 React 中的一个概念,称为将事件从 child 引发到 parent 组件。 parent 将向 child 发送一个事件,后者在发生某些事情时调用该函数。
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>