Reputation: 11
I'm relatively new to frontend developement and I have issues finding the right documentations to help me with this feature. I've been trying to make some markers appear when zooming to a certain level using react-leaflet and React Hooks.
Here is my code for the map:
import React, { useEffect } from 'react';
import { MapContainer, TileLayer, LayerGroup, Marker } from 'react-leaflet';
import TanitMarker from './marker';
import ZoomControlledLayer from './zoom-controlled-layer';
import CustomPopup from './popup';
import './my-map.scss';
function MyMap() {
const hotel = {
thumbnail: {
src: "./hotel.jpg"
},
name: "",
title: "****",
}
useEffect(() => {
console.log('Map is mounted!');
}, []);
return (
<div className="map-container">
<MapContainer center={[35.741728, 10.626254]} zoom={8} scrollWheelZoom={true}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<ZoomControlledLayer zoomRef={7}>
<LayerGroup>
<Marker position={[36.4242, 10.6749]}
riseOnHover={true}>
<CustomPopup site={hotel}></CustomPopup>
</Marker>
</LayerGroup>
</ZoomControlledLayer>
</MapContainer>
</div>
)
}
export default MyMap;
I'm trying to make the LayerGroup
under ZoomControlledLayer
to appear when zoom level 7 is reached.
Thank you in advance.
Upvotes: 1
Views: 950
Reputation: 10676
TileLayers and GridLayers have a maxZoom
and minZoom
property, but it doesn't look like a LayerGroup
has one, so you'll have to implement it manually. First, let's keep track of the map's zoom level in a state variable:
import { MapContainer, useMapEvents } from 'react-leaflet';
function ZoomTracker = ({ setZoom }) => {
const map = useMapEvents({
zoom(){
setZoom(map.getZoom())
}
})
return null
}
function MyMap(){
const [zoom, setZoom] = useState()
return (
<MapContainer>
<ZoomTracker setZoom={setZoom} />
<ZoomControlledLayer zoom={zoom} minZoom={7}>
{...all_the_stuff_in_here}
</ZoomControlledLayer>
</MapContainer>
)
}
So now MyMap
is keeping track of the current zoom level in state, and passing it to the ZoomControlledLayer
component. Now in your ZoomControlledLayer
:
const ZoomControlledLayer = ({ zoom, minZoom, children }) => {
if (zoom >= minZoom){
return (
<>
{children}
</>
);
} else {
return null;
}
}
So ZoomControlledLayer
only renders anything when the maps zoom is the same or greater as your minZoom
. I haven't tested this, but hopefully its enough to get you going. You can read more about using map events in react-leaflet v3 here.
Upvotes: 3