如何在 react-leaflet v.3.x 中使用 dbclick 显示点列表?
How to display a list of points using dbclick in react-leaflet v.3.x?
我对反应还很陌生,我想做的基本上只是在地图上显示一组点。我有一个名为 CovidPoints 的自定义组件,它基本上只是在地图上呈现一个标记。目前我有一个功能组件,可以检测何时发生双击,然后在鼠标位置创建一个点。现在发生的是只有在第一次双击后才创建该点。我希望能够多次双击并每次都创建点。为此,我认为我需要将位置标记函数的 return 附加到点数组道具,但我不确定如何执行此操作。
位置Marker.js:
import {useState} from 'react';
import {useMapEvents, Marker, Popup} from 'react-leaflet';
import CovidPoint from './CovidPoint';
function LocationMarker() {
const [points, setPoints] = useState(null)
const [position, setPosition] = useState(null)
const map = useMapEvents({
dblclick(ev) {
console.log("double clicked");
const coord = map.mouseEventToLatLng(ev.originalEvent);
setPosition(coord);
},
})
return position === null ? null : (
<CovidPoint position={position}></CovidPoint>
)
}
export default LocationMarker;
App.js:
import './App.css';
import * as React from "react";
import { ChakraProvider } from "@chakra-ui/react";
import { MapContainer, TileLayer, Marker, Popup, useMapEvents, useMap } from 'react-leaflet'
import 'leaflet/dist/leaflet.css'
import * as L from 'leaflet';
import SearchBar from './SearchBar';
import CovidPoint from './CovidPoint';
import LocationMarker from './LocationMarker';
class App extends React.Component {
constructor(props){
super(props)
this.state = {
map: null,
points: []
}
}
changePos = (pos, zoom) => {
const {map} = this.state;
if (map) map.flyTo(pos, zoom);
}
render () {
return (
<ChakraProvider resetCSS = {false}>
<div className = "App">
<div id="title">
<h1>
CovidStopSpots
</h1>
<p>A responsive tracker for Covid-19.</p>
</div>
<div id="map">
<MapContainer id = "1" center={[43.653226, -79.3831843]} zoom={13} scrollWheelZoom={false} whenCreated={map => this.setState({ map })}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<CovidPoint position={[43.653226, -79.3831843]} name="point1" information="random point"></CovidPoint>
<CovidPoint position={[50.653226, -79.3831843]} name="point2" information="random point"></CovidPoint>
<LocationMarker></LocationMarker>
</MapContainer>
<div id="searchbar">
<SearchBar changePos = {this.changePos}></SearchBar>
</div>
</div>
</div>
</ChakraProvider>
)
}
}
export default App;
CovidPoint.js:
import './SearchBar.css';
import * as React from "react";
import { MapContainer, Marker } from 'react-leaflet';
import * as L from 'leaflet';
import { Popup } from 'react-leaflet';
class CovidPoint extends React.Component {
constructor (props) {
super(props)
this.state = {
positon: this.props.position,
name: this.props.name,
information: this.props.information,
}
}
render () {
const covidIcon = L.icon({
iconUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Redpoint.svg/768px-Redpoint.svg.png',
iconSize: [30, 30], // size of the icon
iconAnchor: [0, 0], // point of the icon which will correspond to marker's location
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
return (
<div>
<Marker position={this.state.positon} icon={covidIcon}>
<Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup>
</Marker>
</div>
)
}
}
export default CovidPoint;
在您当前的实施中,您不会通过 LocationMarker
在 CovidPoint comp 上传递名称和信息道具。
要显示点列表,您需要有一个 latlngs
的数组,正如您在问题描述中所暗示的那样。因此,您的 LocationMarker comp 应如下所示:
function LocationMarker() {
const [positions, setPositions] = useState([]);
useMapEvents({
dblclick(ev) {
console.log("double clicked");
const { lat, lng } = ev.latlng;
const newPositions = [...positions];
newPositions.push([lat, lng]);
setPositions(newPositions);
}
});
return <CovidPoint positions={positions}></CovidPoint>;
}
你获取包含点击位置坐标的 latlng 对象,然后将它们添加到你的位置数组中。应该是复数,因为会有很多地方,而不是一个。
在您的 CovidPoint 上循环遍历位置以呈现点。您不需要将位置分配给状态变量,除非您想将其作为局部变量进一步操作:
<div>
{this.props.positions.length > 0 &&
this.props.positions.map((position, index) => (
<Marker position={position} icon={covidIcon} key={index}>
{/* <Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup> */}
</Marker>
))}
</div>
那么你需要改变这部分
{/* <Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup> */}
因为它没有从 LocationMarker comp
获取名称和信息作为道具
我对反应还很陌生,我想做的基本上只是在地图上显示一组点。我有一个名为 CovidPoints 的自定义组件,它基本上只是在地图上呈现一个标记。目前我有一个功能组件,可以检测何时发生双击,然后在鼠标位置创建一个点。现在发生的是只有在第一次双击后才创建该点。我希望能够多次双击并每次都创建点。为此,我认为我需要将位置标记函数的 return 附加到点数组道具,但我不确定如何执行此操作。
位置Marker.js:
import {useState} from 'react';
import {useMapEvents, Marker, Popup} from 'react-leaflet';
import CovidPoint from './CovidPoint';
function LocationMarker() {
const [points, setPoints] = useState(null)
const [position, setPosition] = useState(null)
const map = useMapEvents({
dblclick(ev) {
console.log("double clicked");
const coord = map.mouseEventToLatLng(ev.originalEvent);
setPosition(coord);
},
})
return position === null ? null : (
<CovidPoint position={position}></CovidPoint>
)
}
export default LocationMarker;
App.js:
import './App.css';
import * as React from "react";
import { ChakraProvider } from "@chakra-ui/react";
import { MapContainer, TileLayer, Marker, Popup, useMapEvents, useMap } from 'react-leaflet'
import 'leaflet/dist/leaflet.css'
import * as L from 'leaflet';
import SearchBar from './SearchBar';
import CovidPoint from './CovidPoint';
import LocationMarker from './LocationMarker';
class App extends React.Component {
constructor(props){
super(props)
this.state = {
map: null,
points: []
}
}
changePos = (pos, zoom) => {
const {map} = this.state;
if (map) map.flyTo(pos, zoom);
}
render () {
return (
<ChakraProvider resetCSS = {false}>
<div className = "App">
<div id="title">
<h1>
CovidStopSpots
</h1>
<p>A responsive tracker for Covid-19.</p>
</div>
<div id="map">
<MapContainer id = "1" center={[43.653226, -79.3831843]} zoom={13} scrollWheelZoom={false} whenCreated={map => this.setState({ map })}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<CovidPoint position={[43.653226, -79.3831843]} name="point1" information="random point"></CovidPoint>
<CovidPoint position={[50.653226, -79.3831843]} name="point2" information="random point"></CovidPoint>
<LocationMarker></LocationMarker>
</MapContainer>
<div id="searchbar">
<SearchBar changePos = {this.changePos}></SearchBar>
</div>
</div>
</div>
</ChakraProvider>
)
}
}
export default App;
CovidPoint.js:
import './SearchBar.css';
import * as React from "react";
import { MapContainer, Marker } from 'react-leaflet';
import * as L from 'leaflet';
import { Popup } from 'react-leaflet';
class CovidPoint extends React.Component {
constructor (props) {
super(props)
this.state = {
positon: this.props.position,
name: this.props.name,
information: this.props.information,
}
}
render () {
const covidIcon = L.icon({
iconUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Redpoint.svg/768px-Redpoint.svg.png',
iconSize: [30, 30], // size of the icon
iconAnchor: [0, 0], // point of the icon which will correspond to marker's location
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
return (
<div>
<Marker position={this.state.positon} icon={covidIcon}>
<Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup>
</Marker>
</div>
)
}
}
export default CovidPoint;
在您当前的实施中,您不会通过 LocationMarker
在 CovidPoint comp 上传递名称和信息道具。
要显示点列表,您需要有一个 latlngs
的数组,正如您在问题描述中所暗示的那样。因此,您的 LocationMarker comp 应如下所示:
function LocationMarker() {
const [positions, setPositions] = useState([]);
useMapEvents({
dblclick(ev) {
console.log("double clicked");
const { lat, lng } = ev.latlng;
const newPositions = [...positions];
newPositions.push([lat, lng]);
setPositions(newPositions);
}
});
return <CovidPoint positions={positions}></CovidPoint>;
}
你获取包含点击位置坐标的 latlng 对象,然后将它们添加到你的位置数组中。应该是复数,因为会有很多地方,而不是一个。
在您的 CovidPoint 上循环遍历位置以呈现点。您不需要将位置分配给状态变量,除非您想将其作为局部变量进一步操作:
<div>
{this.props.positions.length > 0 &&
this.props.positions.map((position, index) => (
<Marker position={position} icon={covidIcon} key={index}>
{/* <Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup> */}
</Marker>
))}
</div>
那么你需要改变这部分
{/* <Popup>
Name: {this.state.name} <br />
Case Status: {this.state.information}
</Popup> */}
因为它没有从 LocationMarker comp
获取名称和信息作为道具