Skip to content

Instantly share code, notes, and snippets.

@benfavre
Last active May 18, 2024 08:14
Show Gist options
  • Save benfavre/d10a1934402f466df7cbc4d517ade70b to your computer and use it in GitHub Desktop.
Save benfavre/d10a1934402f466df7cbc4d517ade70b to your computer and use it in GitHub Desktop.
Leaflet react
import { LeafletProvider, createLeafletContext } from '@react-leaflet/core';
import { Map as LeafletMap, LatLngBoundsExpression, LatLngExpression, MapOptions, FitBoundsOptions } from 'leaflet';
import React, { useCallback, useEffect, useRef, useState } from 'react';
interface MapContainerProps extends MapOptions {
bounds?: LatLngBoundsExpression;
boundsOptions?: FitBoundsOptions;
center?: LatLngExpression;
children?: React.ReactNode;
className?: string;
id?: string;
placeholder?: React.ReactNode;
style?: React.CSSProperties;
whenReady?: (event?: Event) => void;
}
const MapContainerComponent: React.FC<MapContainerProps> = ({
bounds,
boundsOptions,
center,
children,
className,
id,
placeholder,
style,
whenReady,
zoom,
...options
}) => {
const [props] = useState({ className, id, style });
const [context, setContext] = useState<ReturnType<typeof createLeafletContext> | null>(null);
const mapNodeRef = useRef<HTMLDivElement | null>(null);
const mapInstanceRef = useRef<LeafletMap | null>(null);
const initializeMap = useCallback(() => {
if (mapNodeRef.current !== null && mapInstanceRef.current === null) {
const map = new LeafletMap(mapNodeRef.current, options);
mapInstanceRef.current = map;
if (center != null && zoom != null) {
map.setView(center, zoom);
} else if (bounds != null) {
map.fitBounds(bounds, boundsOptions);
}
if (whenReady != null) {
map.whenReady(whenReady);
}
setContext(createLeafletContext(map));
}
}, [options, center, zoom, bounds, boundsOptions, whenReady]);
useEffect(() => {
initializeMap();
}, [initializeMap]);
/*useEffect(() => {
return () => {
mapInstanceRef.current?.remove();
};
}, []);
*/
const contents = context ? (
<LeafletProvider value={context}>{children}</LeafletProvider>
) : (
placeholder ?? null
);
return (
<div {...props} ref={mapNodeRef}>
{contents}
</div>
);
};
export const MapContainer = MapContainerComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment