如何在点击 geojson 组件时创建标记?
How to create markers on click of geojson component?
我正在尝试在用户单击某个 Geojson 功能时添加标记。我是 React 和 React-leaflet 的新手,正在尝试使用 useState 挂钩来完成此任务。我在这个问题上被困了几天。
这是我的App.js。我导入数据,为我的标记创建一个状态变量和 setter,然后将这些项目传递给我的组件 <MyData/>
和 <MyMarkers/>
.
import "./styles.css";
import React, { useState } from 'react'
import {MapContainer, TileLayer} from 'react-leaflet'
import L from 'leaflet'
import someData from './data.geojson'
import MyData from './components/MyData.js'
import MyMarkers from './components/MyMarkers.js'
// import bugged marker
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
// set the default icon
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [2, -40],
});
L.Marker.prototype.options.icon = DefaultIcon;
export default function App() {
// create state variable and setter for the markers
let [markers, setMarkers] = useState([])
// import geojson data
let data= JSON.parse(someData)
return (
<>
<MapContainer
doubleClickZoom={false}
id="mapId"
zoom={14}
center={[37.37569444, -91.5528056]}
>
<TileLayer
url="https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}"
attribution="Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri"
/>
<MyData data={data} markers = {markers} setMarkers ={setMarkers}/>
{markers.length >0 && <MyMarkers markers={markers}/>}
</MapContainer>
</>
);
}
这是我的 MyData 组件,它显示 geojson 数据。它接收 geojson 数据、对象数组和设置标记状态的函数。
import React from 'react';
import { GeoJSON } from 'react-leaflet';
function MyData ({data, markers, setMarkers}) {
// data not null, return the geojson component
if (data) {
return <GeoJSON pathOptions={ { color: "red" } } data={data} eventHandlers={{
// click handler for geojson component
click: (e) => {
// push the latlng object to the markers array
markers.push(e.latlng)
// set the state using the setter...why does this not render markers?
setMarkers(markers)
}
}} />;
} else {
return null;
}
};
export default MyData
这是我的 MyMarkers 组件,它遍历标记数组,我将其作为道具传递,理想地在每个位置创建标记组件。 (这不起作用)
import React from 'react';
import { Marker } from 'react-leaflet';
function MyMarkers ({markers}) {
// check length of the markers
if (markers.length > 0){
// iterate through the array of markers creating a marker with unique id at given latlngs
markers.map((position, id) => {
return <Marker key={id} position={position}/>
})
} else {
return null;
}
};
export default MyMarkers
我可以在地图上绘制我的 geojson 数据,但无法在单击我的 <MyData/>
组件时显示标记。我在这里错过了什么?我的理解是,当尝试更新同级组件( <MyData/>
和 <MyMarkers/>
)的状态时,需要将状态提升到一个共同的祖先(在这种情况下为 <App/>
),这就是我所拥有的试图去做。如何从 <MyData/>
内部成功更新状态 onclick 以呈现标记?
Here 也是上述问题和代码的沙箱。
谢谢
-首先你要改变数组。因此,该组件不会重新呈现。您应该复制标记,然后推送新状态。
<GeoJSON
pathOptions={{ color: "red" }}
data={data}
eventHandlers={{
// click handler for geojson component
click: (e) => {
const newMarkers=[...markers];
newMarkers.push(e.latlng);
console.log(newMarkers)
setMarkers(newMarkers);
}
}}
/>
-其次,您已经在此处检查要渲染的标记 markers.length !== 0
,在我看来它应该在 0 以上更好:{markers.length > 0 && <MyMarkers markers={markers} />}
为什么要重新检查 Markers
组件内部。保持简单:
function MyMarkers({ markers }) {
// iterate through the array of markers creating a marker with unique id at given latlngs
return markers.map((position, id) => {
return <Marker key={id} position={[position.lat, position.lng]} />;
});
}
最后但同样重要的是,标记 url 图标不正确。将其替换为
iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
例如
我正在尝试在用户单击某个 Geojson 功能时添加标记。我是 React 和 React-leaflet 的新手,正在尝试使用 useState 挂钩来完成此任务。我在这个问题上被困了几天。
这是我的App.js。我导入数据,为我的标记创建一个状态变量和 setter,然后将这些项目传递给我的组件 <MyData/>
和 <MyMarkers/>
.
import "./styles.css";
import React, { useState } from 'react'
import {MapContainer, TileLayer} from 'react-leaflet'
import L from 'leaflet'
import someData from './data.geojson'
import MyData from './components/MyData.js'
import MyMarkers from './components/MyMarkers.js'
// import bugged marker
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
// set the default icon
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [2, -40],
});
L.Marker.prototype.options.icon = DefaultIcon;
export default function App() {
// create state variable and setter for the markers
let [markers, setMarkers] = useState([])
// import geojson data
let data= JSON.parse(someData)
return (
<>
<MapContainer
doubleClickZoom={false}
id="mapId"
zoom={14}
center={[37.37569444, -91.5528056]}
>
<TileLayer
url="https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}"
attribution="Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri"
/>
<MyData data={data} markers = {markers} setMarkers ={setMarkers}/>
{markers.length >0 && <MyMarkers markers={markers}/>}
</MapContainer>
</>
);
}
这是我的 MyData 组件,它显示 geojson 数据。它接收 geojson 数据、对象数组和设置标记状态的函数。
import React from 'react';
import { GeoJSON } from 'react-leaflet';
function MyData ({data, markers, setMarkers}) {
// data not null, return the geojson component
if (data) {
return <GeoJSON pathOptions={ { color: "red" } } data={data} eventHandlers={{
// click handler for geojson component
click: (e) => {
// push the latlng object to the markers array
markers.push(e.latlng)
// set the state using the setter...why does this not render markers?
setMarkers(markers)
}
}} />;
} else {
return null;
}
};
export default MyData
这是我的 MyMarkers 组件,它遍历标记数组,我将其作为道具传递,理想地在每个位置创建标记组件。 (这不起作用)
import React from 'react';
import { Marker } from 'react-leaflet';
function MyMarkers ({markers}) {
// check length of the markers
if (markers.length > 0){
// iterate through the array of markers creating a marker with unique id at given latlngs
markers.map((position, id) => {
return <Marker key={id} position={position}/>
})
} else {
return null;
}
};
export default MyMarkers
我可以在地图上绘制我的 geojson 数据,但无法在单击我的 <MyData/>
组件时显示标记。我在这里错过了什么?我的理解是,当尝试更新同级组件( <MyData/>
和 <MyMarkers/>
)的状态时,需要将状态提升到一个共同的祖先(在这种情况下为 <App/>
),这就是我所拥有的试图去做。如何从 <MyData/>
内部成功更新状态 onclick 以呈现标记?
Here 也是上述问题和代码的沙箱。
谢谢
-首先你要改变数组。因此,该组件不会重新呈现。您应该复制标记,然后推送新状态。
<GeoJSON
pathOptions={{ color: "red" }}
data={data}
eventHandlers={{
// click handler for geojson component
click: (e) => {
const newMarkers=[...markers];
newMarkers.push(e.latlng);
console.log(newMarkers)
setMarkers(newMarkers);
}
}}
/>
-其次,您已经在此处检查要渲染的标记 markers.length !== 0
,在我看来它应该在 0 以上更好:{markers.length > 0 && <MyMarkers markers={markers} />}
为什么要重新检查 Markers
组件内部。保持简单:
function MyMarkers({ markers }) {
// iterate through the array of markers creating a marker with unique id at given latlngs
return markers.map((position, id) => {
return <Marker key={id} position={[position.lat, position.lng]} />;
});
}
最后但同样重要的是,标记 url 图标不正确。将其替换为
iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
例如