Reputation: 3221
I am using react-leaflet (v3.2.5) with leaflet (v1.8.0). We need pretty custom zoom buttons and one additional 'home' like button on the map, which look like this:
So I am trying to create a custom controls component like this (<FeatherIcon />
is another component from our codebase):
function MapControls() :JSX.Element {
const map = useMap();
return <div className="leaflet-top leaflet-right vertical-controls clickable">
<span className="control-icon-box" onClick={() => { console.log('in', map); map.zoomIn();}}><FeatherIcons iconId='plus-circle' className="feather vertical-control-icon" /></span>
<span className="control-icon-box" onClick={() => { map.zoomOut();}}><FeatherIcons iconId='minus-circle' className="feather vertical-control-icon" /></span>
<span className="control-icon-box"><FeatherIcons iconId='target' className="feather vertical-control-icon" /></span>
</div>
}
I want to use it like this
<MapContainer center={[buildingsData.geoCenter.y, buildingsData.geoCenter.x]} zoom={buildingsData.geoCenter.zoom} scrollWheelZoom={true}
zoomControl={false} zoomDelta={0.5}>
<!-- other stuff -->
<MapControls />
</MapContainer>
But the click handler is not added in the MapContainer
context (like mentioned here).
Do I need to use something like
const minusRef = useRef(null);
useEffect(() => {
function minusClick() { /* doing stuff */ }
if (minusRef.current !== null) {
minusRef.current.addEventListener('click', minusClick);
}
return () => {
if (minusRef.current !== null) {
minusRef.current.removeEventLister('click', minusClick);
}
}
}, [map]);
This solution here is not really clear to me:
I am not sure how to achieve that using your approach where react-leaflet's wrapper ZoomControl is not a child of Map wrapper when you try to place it outside the Map wrapper.
However, for a small control like the ZoomControl, an easy solution would be to create a custom Zoom component, identical to the original, construct it easily using the native css style and after accessing the map element, invoke the zoom in and out methods respectively.
In the below example I use react-context to save the map element after the map loads:
const map = mapRef.current.leafletElement; setMap(map); }, [mapRef, setMap]); ``` and then here use the map reference to make a custom Zoom component identical to the native (for css see the demo): ``` const Zoom = () => { const { map } = useContext(Context); // etc ```
Upvotes: 1
Views: 117