How To Integrate Leaflet Maps in React 2022
Leaflet is an open-source JavaScript library for mobile-friendly interactive maps. In this tutorial, we will integrate leaflet maps in react using react-leaflet package.
1. Let's install create-react-app package.
npm i -g create-react-app
2. Create a new react project
create-react-app react-leaflet-maps
cd react-leaflet-maps
3. Install leaflet, react-leaflet packages inside the project.
npm i leaflet react-leaflet
4. Create folder components inside the src folder. Inside this folder create map.component.jsx file.
import React, { useRef, useState } from "react";
import Leaflet from "leaflet"
import "leaflet/dist/leaflet.css"
import { MapContainer, TileLayer, Marker, Popup, useMapEvents } from "react-leaflet"
import markerIcon from "leaflet/dist/images/marker-icon.png"
import markerShadow from "leaflet/dist/images/marker-shadow.png"
import markerRetina from "leaflet/dist/images/marker-icon-2x.png"
Leaflet.Icon.Default.mergeOptions({
iconRetinaUrl: markerRetina,
iconUrl: markerIcon,
shadowUrl: markerShadow
});
const MapComponent = () => {
const mapRef = useRef();
const zoom = 16;
const containerStyle = {
width: "100%",
height: "400px"
}
const center = {
lat: 28.626137,
lng: 79.821603
}
const initialMarkers = [
{
position: {
lat: 28.625485,
lng: 79.821091
},
draggable: true
},
{
position: {
lat: 28.625293,
lng: 79.817926
},
draggable: false
},
{
position: {
lat: 28.625182,
lng: 79.81464
},
draggable: true
},
];
const [markers, setMarkers] = useState(initialMarkers);
const mapClicked = async (event) => {
console.log(event.latlng.lat, event.latlng.lng)
}
const markerClicked = (marker, index) => {
console.log(marker.position.lat, marker.position.lng)
}
const markerDragEnd = (event, index) => {
console.log(event.lat, event.lng)
}
return (
<MapContainer
style={containerStyle}
center={center}
zoom={zoom}
scrollWheelZoom={false}
ref={mapRef}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MapContent
onClick={mapClicked}
/>
{markers.map((marker, index) => (
<MarkerContent
key={index}
position={marker.position}
draggable={marker.draggable}
onMarkerClick={event => markerClicked(marker, index)}
onDragEnd={event => markerDragEnd(event, index)}
/>
))}
</MapContainer>
);
};
const MapContent = ({ onClick }) => {
const map = useMapEvents({
click: event => onClick(event)
})
return null;
}
const MarkerContent = (props) => {
const markerRef = useRef();
const { position, draggable, onMarkerClick, onDragEnd } = props;
return <Marker
position={position}
draggable={draggable}
eventHandlers={{
click: event => onMarkerClick(event),
dragend: () => onDragEnd(markerRef.current.getLatLng())
}}
ref={markerRef}
>
<Popup>
<b>{position.lat}, {position.lng}</b>
</Popup>
</Marker>
}
export default MapComponent;
You can easily add/remove markers. also, you can pass additional properties in the marker object based on your requirement.
(a). Add a marker
const allMarkers = [...markers];
const marker = {
position: {
lat: 28.625043,
lng: 79.810135
},
draggable: true
}
allMarkers.push(marker);
setMarkers(allMarkers)
(b). Remove a marker
Example:- Remove 3rd marker of markers array.
const index = 2;
const filteredMarkers = markers.filter((m, i) => i != index);
setMarkers(filteredMarkers)
(c). Update marker properties
Example:- Update 3rd marker of markers array.
const index = 2;
const allMarkers = [...markers];
allMarkers[index]= { ...allMarkers[index], position: { lat: 28.625043, lng: 79.810135 } };
setMarkers(allMarkers)
5. Open the App.js file and make the following changes.
import React from "react";
import "./App.css";
import MapComponent from "./components/map.component";
function App() {
return (
<div className="App">
<h1>React Leaflet Maps</h1>
<MapComponent/>
</div>
);
}
export default App;
6. Finally start the project.
npm start
open http://localhost:3000 in the browser.
Extras:- Reverse Geocoding
7. Install leaflet-control-geocoder npm package.
npm i leaflet-control-geocoder
8. Import leaflet-control-geocoder
import React, { useRef, useState } from "react";
import Leaflet from "leaflet"
import "leaflet/dist/leaflet.css"
import "leaflet-control-geocoder";
9. Create a function.
const getAddress = (lat, lng) => {
const geocoder = Leaflet.Control.Geocoder.nominatim();
return new Promise((resolve, reject) => {
geocoder.reverse(
{ lat, lng },
mapRef.current.getZoom(),
results => results.length ? resolve(results[0].name) : reject(null)
);
})
}
You can use this function by passing lat and lng.
const mapClicked = async (event) => {
console.log(event.latlng.lat, event.latlng.lng)
const address = await getAddress(event.latlng.lat, event.latlng.lng)
console.log(address)
}
Checkout my full react-leaflet-maps example.
https://github.com/ultimateakash/react-leaflet-maps
If you facing any issues. don't hesitate to comment below. I will be happy to help you.
Thanks.
Leave Your Comment