Maps in React

Using React-Leaflet with OpenStreetMap is a popular and effective choice for working with maps in React.

Another widely considered option is employing Google Maps. However, utilizing Google Maps necessitates the setup of a Google Developer account and the acquisition of an API key. Additionally, integrating Google Maps into React applications might pose a greater level of complexity.

React-Leaflet is specifically designed to work seamlessly with React. It provides a set of React components that makes it easy to integrate maps into React applications. React-Leaflet is a React wrapper for Leaflet. Leaflet is a widely used and well-documented JavaScript library for interactive maps. Both React-Leaflet and Leaflet have large and active communities. This means you can find a wealth of resources, tutorials, and plugins to extend the functionality of your maps. Any issues or challenges you encounter are likely to have been faced by others, and solutions can be readily available. OpenStreetMap (OSM) is a collaborative project that creates a free, editable map of the world. It provides high-quality map data that is free to use, making it an excellent choice for developers.

Both React-Leaflet and Leaflet provide a high degree of customization. You can easily change map styles, add markers, polygons, popups, and interact with various events. This flexibility allows you to tailor the maps to meet the specific needs of your application. With React-Leaflet, it’s straightforward to create responsive maps that adapt well to different screen sizes. This is crucial for ensuring a positive user experience across various devices, including desktops, tablets, and mobile devices. In summary, React-Leaflet, coupled with OpenStreetMap, offers a powerful and flexible solution for incorporating maps into React applications. I’ll guide you through the steps of setting up a simple map in a React application using React-Leaflet and OpenStreetMap.

Step 1: Create a new React App

If you are using a React online editor, you can proceed to step 2.

Create a new project in VS code.

Step 2: Install React-Leaflet

React-Leaflet is a third-party charting library for React and is not a part of the React core. To integrate React-Leaflet into your project, open a terminal window within your project directory and install it by typing the following command. In online editors, you can achieve the same by entering the command in the specific section where you manage libraries.

npm install react-leaflet

To ensure that you have installed it correctly, you can check your package.json file in the root folder of your project, and you should find ‘react-leaflet’ listed in the dependencies section.

Step 3: Remove default CSS

When you create a new React project, default CSS files such as App.css and index.css are generated. It is advisable to remove them and add CSS based on your current project requirements, as the default CSS may impact the map component, causing it not to display correctly.

Step 4: Create a Map Component

Create a new file named Map.jsx within the src directory and set up a basic map component using React-Leaflet. Make sure to include the required components and associated CSS file using import statements.

import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

The initial configuration of the map is shown below. This configuration displays the world map with a zoom level of 5 and centers the view on the point defined in the ‘position’ constant. Additionally, it includes a marker at the center of the screen and a simple popup.

import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const Map = () => {
  const position = [63, 16]; // the position on the map which should be shown in the center of the screen 

  return (
    <MapContainer center={position} zoom={5} style={{ height: '100vh', width: '100wh' }}>
      <TileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      />
      <Marker position={position}>
        <Popup>
          A sample marker in React-Leaflet!
        </Popup>
      </Marker>
    </MapContainer>
  );
};

export default Map;

Step 5: Add to the App.js

Replace the content of src/App.jsx with the following code to to add the Map component to the parent component in your app.

import React from 'react';

import Map from './map';

function App() {
  return (
    <div>
      <Map />
    </div>
  );
}

export default App;

Step 6: Run the Application

Save your files and run your application.

To run the app locally, use the command: `npm run dev`. If you are using an online editor, please refer to the editor's instructions on how to run the app.

Step 7: Make the map interactive

To make the map interactive, I want to add two markers to the map. When we have both markers on the map, clicking on one of them will show a small popup indicating the direct distance between them in kilometers. To achieve this, we need three component states to save the positions of the markers and to handle placing markers on the map.

    const [marker1, setMarker1] = useState(null);
    const [marker2, setMarker2] = useState(null);
    const [current, setCurrent] = useState(1);

We also need to activate the click event on the map. I use useMapEvents to achieve this. Don’t forget to import useMapEvents.

In the following code, a marker is placed on the map based on the value of ‘current.’ I have limited to put only two markers on the map. Therefore, there are two if statements in the following code.

    function LocationMarker() {
        useMapEvents({
            click(e) {
                if (current == 1) {
                    setMarker1(e.latlng); setCurrent(2);
                }
                else if (current == 2) {
                    setMarker2(e.latlng); setCurrent(1);
                }
            }
        })
    }

With the following code, we display markers on the map at the same position where the user has clicked. We use ‘&&’ to ensure that both marker1 and marker2 have valid values. Otherwise we do not show them. Also, add <LocationMarker> at the end to activate the click event.

            {marker1 && <Marker position={marker1}>
            </Marker>
            }
            {marker2 && <Marker position={marker2}>
            </Marker>
            }
            <LocationMarker></LocationMarker>

Step 8: Calculate the distance between two points

To calculate the distance between two markers, both markers must be placed on the map. If only one marker is placed on the map, the distance shown will be 0 km. The following code calculates the distance.

                <Popup>
                    The distance between two points is{marker2 ? (marker1.distanceTo(marker2) / 1000).toFixed(0) + " km" : "0 km"}
                </Popup>

Step 9: Final code for map.jsx

Here is final code in map.jsx.

import React, { useState } from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMapEvents } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
const Map = () => {
    const position = [63, 16]; // the position on the map which should be shown in the center of the screen 

    const [marker1, setMarker1] = useState(null);
    const [marker2, setMarker2] = useState(null);
    const [current, setCurrent] = useState(1);


    function LocationMarker() {
        useMapEvents({
            click(e) {
                if (current == 1) {
                    setMarker1(e.latlng); setCurrent(2);
                }
                else if (current == 2) {
                    setMarker2(e.latlng); setCurrent(1);
                }
            }
        })
    }

    return (
        <MapContainer center={position} zoom={5} style={{
            height: '100vh', width: '100wh'
        }}>
            <TileLayer
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            />
            {marker1 && <Marker position={marker1}>
                <Popup>
                    The distance between two points is {marker2 ? (marker1.distanceTo(marker2) / 1000).toFixed(0) + " km" : " 0 km"}
                </Popup>
            </Marker>
            }
            {marker2 && <Marker position={marker2}>
                <Popup>
                    The distance between two points is {marker1 ? (marker1.distanceTo(marker2) / 1000).toFixed(0) + " km" : " 0 km"}
                </Popup>
            </Marker>
            }
            <LocationMarker></LocationMarker>
        </MapContainer >
    );
};

export default Map;

And here is the output of this app.

You can download the source code of the app here. Don’t forget to run ‘npm install’ before using ‘npm run dev’ to ensure all dependencies are installed.”

Useful Links

React Leaflet

Events in React Leaflet

OpenStreenMaps

Scroll to Top