Я использую React-листовку для получения позиции. Я создал текст ввода для поиска, чтобы разместить маркер по адресу API, и я хочу, чтобы можно было перемещать маркер более точно.
Я установил маркер на «draggable = true», но я хочу обновить положение x и y и отобразить его во всплывающем окне. Как это сделать?
import React, { useEffect, useState } from 'react'
import 'leaflet/dist/leaflet.css'
import Leaflet from "leaflet";
import L from "leaflet";
import { MapContainer, Marker, useMap, TileLayer, Popup } from 'react-leaflet'
export default function App(text: any) {
const [x, setX] = useState(2.3522219)
const [y, setY] = useState(48.856614)
console.info(y, x);
const icon = new Leaflet.DivIcon({
className: 'custom-div-icon',
html:
"<div style='background-color:#c30b82;' class='marker-pin'></div><i class='material-icons'><img src='img/marker-icon.png'></i>",
iconSize: [30, 42],
iconAnchor: [15, 42],
popupAnchor: [-3, -42]
})
function SetViewOnClick({ coords }: any) {
const map = useMap()
map.setView(coords, map.getZoom())
return null
}
useEffect(() => {
if (text.text) {
setX(text.text.features[0].geometry.coordinates[0])
setY(text.text.features[0].geometry.coordinates[1])
}
}, [text])
return (
<MapContainer
center = {[y, x]}
attributionControl = {false}
zoomControl = {false}
zoom = {12}
style = {{
height: '350px',
position: 'relative',
outline: 'none',
maxWidth: '696px',
display: 'block',
margin: '15px auto',
width: '100%'
}}
>
<TileLayer url = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<Marker position = {[y, x]} icon = {icon} draggable = {true}>
<Popup>
<span>
{text.text
? text.text.query
: "Location Default"}
</span>
</Popup>
<SetViewOnClick coords = {[y, x]} />
</Marker>
</MapContainer>
)
}
Да хочу сразу показать новую позицию.
ОК. Я думал так же. Я написал ответ. Посмотрите и дайте мне знать, поможет ли это вам





Используйте eventHandlers на Marker comp в сочетании с маркером ref для обновления x, y.
const markerRef = useRef(null);
const eventHandlers = useMemo(
() => ({
dragend() {
const marker = markerRef.current;
if (marker != null) {
console.info(marker.getLatLng());
const { lat, lng } = marker.getLatLng();
setX(lng);
setY(lat);
setMarkerDragged(true);
}
}
}),
[]
);
...
<Marker
position = {[y, x]}
icon = {icon}
draggable = {"true"}
ref = {markerRef}
eventHandlers = {eventHandlers}
>
<Popup>
<span>{popup()}</span>
</Popup>
<SetViewOnClick coords = {[y, x]} />
</Marker>
Вы также можете использовать флаг для отображения нового всплывающего сообщения при перетаскивании маркера, но, в конце концов, это зависит от вас, как вы будете отображать всплывающее окно для оценки трех различных условий.
const [markerDragged, setMarkerDragged] = useState(false);
const popup = () => {
if (markerDragged) return `New latitude: ${y}, new longitude: ${x}`;
return text ? text.query : "Location Default";
};
Вам придется изменить тернар во всплывающем окне, потому что он не будет выполнять условие. У вас будет 3 случая вместо 2. Как узнать, какой текст показывать? Если вы не хотите, чтобы при перетаскивании маркера сразу отображалась новая позиция