我正在获取用户的位置并将其设置为“onSuccess”函数的新状态, 该组件不会重新渲染。 在检查了很多之后,我看到 react 没有将其视为状态的变化,因为在这种情况下它是一个数组,并且它没有通过 react 的“相等”检查作为已更改的状态。 有了这个,我尝试过的一切都没有奏效。有什么想法吗?
import { useEffect, useState } from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
export default function Map() {
const [location, setLocation] = useState([52.234, 13.413]);
const onSuccess = (position) => {
let userLocation = [position.coords.latitude, position.coords.longitude];
setLocation([...userLocation]);
};
useEffect(() => {
if (!("geolocation" in navigator)) {
alert("no Geolocation available");
}
navigator.geolocation.getCurrentPosition(onSuccess);
}, []);
console.log(location);
return (
<>
<MapContainer
className="leaflet-map"
center={location}
zoom={11}
scrollWheelZoom={false}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[51.505, -0.09]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
</>
);
}
答案 0 :(得分:2)
即使 MapContainer
道具如文档中所述发生更改,center
似乎也不会在安装后重新定位:
https://react-leaflet.js.org/docs/api-map
<块引用>除了它的子项,MapContainer 的 props 是不可变的:在第一次设置后更改它们不会对 Map 实例或其容器产生影响。
您可以通过传递您在 MapContainer
更改时更改的 key
属性来强制替换 location
,例如:
<MapContainer
key={`${location[0]}-${location[1]}`}
或者调查 react-leaflet
中的其他选项,例如 useMap
以访问 Leaflet Map 实例并调用 map.setView(...)
https://leafletjs.com/reference-1.7.1.html#map-setview
答案 1 :(得分:1)
您能否确认完全调用了 onSuccess
?可能是 getCurrentPosition
遇到了错误,所以用两个参数调用它会很好:
navigator.geolocation.getCurrentPosition(onSuccess, onError);
您还应该在 onSuccess
依赖项中包含 useEffect
。
useEffect(() => {
if (!("geolocation" in navigator)) {
alert("no Geolocation available");
}
navigator.geolocation.getCurrentPosition(onSuccess);
}, [onSuccess]);
并且为了防止由于 getCurrentPosition
更改而多次调用 onSuccess
,您还应该 useCallback
依赖于 setLocation
:
const onSuccess = useCallback((position) => {
let userLocation = [position.coords.latitude, position.coords.longitude];
setLocation([...userLocation]);
}, [setLocation]);