Reputation: 1328
I am trying to integrate leaflet in my react library, but the issue i am facing is that even though i have set initial bounds and zoom set for the MapContainer, sometimes on page reload the map zooms out and gets set instead of following the bounds which I have provided to it.
Here is the code below
const LeafletMap = () => {
const [map, setMap] = useState(null)
useEffect(() => {
if (map) {
map.on('moveend', moveEnd)
map.on('zoomend', zoomEnd)
setTimeout(() => {
map?.invalidateSize(true)
}, 100)
}
}, [map])
function handleMapLoad(s) {
setMap(s.target)
}
function moveEnd() {
console.log(map.getBounds())
}
const zoomEnd = () => {
console.log(map.getZoom())
}
return (
<div>
<MapContainer
bounds={[
[
42.2243013614939,
-121.2243013614939
],
[
22.2243013614939,
-81.2243013614939
]
]}
maxBounds={[
[85, -180],
[-85, 180]
]}
zoom={3}
minZoom={1}
whenReady={handleMapLoad}
worldCopyJump={false}
>
<TileLayer url={url} attribution={attribution} />
</MapContainer>
</div>
)
}
The bounds are fetched from my database and there is no resetting of the zoom level and the bounds, still somehow sometimes it sets the bound correctly and sometimes not
Upvotes: 1
Views: 86
Reputation: 36
In Leaflet, the parameters specified in the MapContainer component do not mutate. This means that the parameters initially set for the component remain unchanged, even if these parameters are updated later after receiving new data.
To modify the initial bounds parameters, you can use useEffect and include the data received from the API in the dependencies.
For example:
useEffect(() => {
if (!map) return;
map.fitBounds(data.bounds);
map.setView(data.centerMapCoordinates, data.zoom);
}, [data]);
Alternatively, you can delay rendering the map until the data is loaded. This should resolve the issue on the initial page load. However, if you’re working with dynamic data and filters, it’s recommended to use a useEffect to reassign the map settings dynamically.
You can also add a center prop to the MapContainer component and provide the coordinates to center the map. Additionally, consider adding the prop maxBoundsViscosity={1.0} to restrict scrolling beyond the map's boundaries, preventing users from scrolling past its limits.
Note that when you set both bounds and zoom at the same time, a conflict may arise.
bounds: Sets the geographical bounds of the map to ensure the specified area (bounding box) is visible. Leaflet automatically calculates the appropriate zoom level and centers the map to display the entire area.
zoom: Sets a specific zoom level for the map. It is independent of the bounds and center but works in conjunction with center to define the specific view.
When you set both bounds and zoom at the same time:
bounds overrides zoom: If bounds is specified, Leaflet automatically calculates the appropriate zoom level, ignoring the given zoom value. This can lead to unpredictable map behavior, especially if zoom is used for manual zoom control.
Use only bounds if you want to show a specific area.
Remove the zoom prop and set only bounds in MapContainer. This will allow Leaflet to automatically choose the zoom level.
Or use zoom and center if you want to manually control the map.
Remove bounds and specify the map's center (center) and zoom level (zoom) for full manual control.
Upvotes: 0