Core concepts
React-Leaflet uses ⚛️ React’s lifecycle methods to call the relevant Leaflet handlers, which has a few consequences:
DOM rendering
React does not render Leaflet layers to the DOM, this rendering is done by Leaflet itself.
React only renders the map container for the Map component and potentially empty <div>
elements for components having multiple children.
Component properties
The properties passed to the components are used to create the relevant Leaflet instance when the component will mount. When adding a component, all these properties should be supported as they are by Leaflet, however they will not be updated in the UI when they change unless they are referenced in the documentation as dynamic, which are the ones handled by the components to call the relevant Leaflet method to update it.
Dynamic properties changes are compared by reference, except for properties documenting how their changes are compared in other ways.
Component context
React-Leaflet v2 uses ⚛️ React’s context API to make Leaflet elements available to other element that need it.
If you create custom components, make sure to learn about React’s context and how it is used by React-Leaflet.
Lifecycle process
- The top-level
Map
renders an empty<div>
to contain the map. - The
Map
‘scomponentDidMount()
handler instantiates aLeaflet.Map()
for the created<div>
with the component properties and sets this instance in state. This instance is made available in the context. - The
Map
‘srender()
handler is executed again, this time rendering its children components. - For each child component, the
componentDidMount()
handler is called and instantiates the relevant Leaflet instance for this element using the component properties and context. - The
render()
handler for each child is called, either returningnull
or rendering its own children. - When the
componentDidUpdate()
handler of a component is called, it updates its Leaflet instance according to its supported dynamic properties. - When the
componentWillUnmount()
handler of a component is called, it removes its layer from the map if relevant.
Limitations
- Leaflet makes direct calls to the DOM when it is loaded, therefore this library is not compatible with server-side rendering.
- The components exposed are abstractions for Leaflet layers, not DOM elements. Some of them have properties that can be updated directly by calling the setters exposed by Leaflet while others should be completely replaced, by setting an unique value on their
key
property so that they are properly handled by React’s algorithm.
Leaflet Quick Start Guide
This step-by-step guide will quickly get you started on Leaflet basics, including setting up a Leaflet map, working with markers, polylines and popups, and dealing with events.
Preparing your page
Before writing any code for the map, you need to do the following preparation steps on your page:
- Include Leaflet CSS file in the head section of your document:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
- Include Leaflet JavaScript file after Leaflet’s CSS:
<!-- Make sure you put this AFTER Leaflet's CSS --> <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js" integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg==" crossorigin=""></script>
- Put a
div
element with a certainid
where you want your map to be:<div id="mapid"></div>
- Make sure the map container has a defined height, for example by setting it in CSS:
#mapid { height: 180px; }
Now you’re ready to initialize the map and do some stuff with it.
Setting up the map
Let’s create a map of the center of London with pretty Mapbox Streets tiles. First we’ll initialize the map and set its view to our chosen geographical coordinates and a zoom level:
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
By default (as we didn’t pass any options when creating the map instance), all mouse and touch interactions on the map are enabled, and it has zoom and attribution controls.
Note that setView
call also returns the map object — most Leaflet methods act like this when they don’t return an explicit value, which allows convenient jQuery-like method chaining.
Next we’ll add a tile layer to add to our map, in this case it’s a Mapbox Streets tile layer. Creating a tile layer usually involves setting the URL template for the tile images, the attribution text and the maximum zoom level of the layer. In this example we’ll use the mapbox.streets
tiles from Mapbox’s “Classic maps” (in order to use tiles from Mapbox, you must also request an access token).
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: 'your.mapbox.access.token'
}).addTo(mymap);
Make sure all the code is called after the div
and leaflet.js
inclusion. That’s it! You have a working Leaflet map now.
It’s worth noting that Leaflet is provider-agnostic, meaning that it doesn’t enforce a particular choice of providers for tiles. You can try replacing mapbox.streets
with mapbox.satellite
, and see what happens. Also, Leaflet doesn’t even contain a single provider-specific line of code, so you’re free to use other providers if you need to (we’d suggest Mapbox though, it looks beautiful).
Whenever using anything based on OpenStreetMap, an attribution is obligatory as per the copyright notice. Most other tile providers (such as MapBox, Stamen or Thunderforest) require an attribution as well. Make sure to give credit where credit is due.
Markers, circles and polygons
Besides tile layers, you can easily add other things to your map, including markers, polylines, polygons, circles, and popups. Let’s add a marker:
var marker = L.marker([51.5, -0.09]).addTo(mymap);
Adding a circle is the same (except for specifying the radius in meters as a second argument), but lets you control how it looks by passing options as the last argument when creating the object:
var circle = L.circle([51.508, -0.11], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500
}).addTo(mymap);
Adding a polygon is as easy:
var polygon = L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
]).addTo(mymap);
Working with popups
Popups are usually used when you want to attach some information to a particular object on a map. Leaflet has a very handy shortcut for this:
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
circle.bindPopup("I am a circle.");
polygon.bindPopup("I am a polygon.");
Try clicking on our objects. The bindPopup
method attaches a popup with the specified HTML content to your marker so the popup appears when you click on the object, and the openPopup
method (for markers only) immediately opens the attached popup.
You can also use popups as layers (when you need something more than attaching a popup to an object):
var popup = L.popup()
.setLatLng([51.5, -0.09])
.setContent("I am a standalone popup.")
.openOn(mymap);
Here we use openOn
instead of addTo
because it handles automatic closing of a previously opened popup when opening a new one which is good for usability.
Dealing with events
Every time something happens in Leaflet, e.g. user clicks on a marker or map zoom changes, the corresponding object sends an event which you can subscribe to with a function. It allows you to react to user interaction:
function onMapClick(e) {
alert("You clicked the map at " + e.latlng);
}
mymap.on('click', onMapClick);
Each object has its own set of events — see documentation for details. The first argument of the listener function is an event object — it contains useful information about the event that happened. For example, map click event object (e
in the example above) has latlng
property which is a location at which the click occurred.
Let’s improve our example by using a popup instead of an alert:
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
Try clicking on the map and you will see the coordinates in a popup. View the full example →
Now you’ve learned Leaflet basics and can start building map apps straight away! Don’t forget to take a look at the detailed documentation or other examples.