I am getting user's location and setting it as the new state at "onSuccess" function, the component doesn't re-render. After checking a lot i have seen that react doesn't see it as a change of state because it is an array in that case and it doesn't pass react's "equality" check as a state that was changed. With that, nothing that i have tried has worked. any ideas?
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>
</>
);
}
It looks like MapContainer
does not recenter after mounting even if the center
prop is changed as mentioned in the docs:
https://react-leaflet.js.org/docs/api-map
Except for its children, MapContainer props are immutable: changing them after they have been set a first time will have no effect on the Map instance or its container.
You could force replacing the MapContainer
by passing a key
prop that you change whenever location
changes, for example:
<MapContainer
key={`${location[0]}-${location[1]}`}
Or investigating other options in react-leaflet
such as useMap
to get access to the Leaflet Map instance and calling map.setView(...)
https://leafletjs.com/reference-1.7.1.html#map-setview
Are you able to confirm that onSuccess
is called at all? It may be that getCurrentPosition
is running into an error, so calling it with two arguments would be good:
navigator.geolocation.getCurrentPosition(onSuccess, onError);
You should also include onSuccess
in the useEffect
dependencies.
useEffect(() => {
if (!("geolocation" in navigator)) {
alert("no Geolocation available");
}
navigator.geolocation.getCurrentPosition(onSuccess);
}, [onSuccess]);
And to prevent multiple calls to getCurrentPosition
due to onSuccess
changing, you should also useCallback
with the dependency on setLocation
:
const onSuccess = useCallback((position) => {
let userLocation = [position.coords.latitude, position.coords.longitude];
setLocation([...userLocation]);
}, [setLocation]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.