Leaflet Map with React — part I. This tutorial is for beginners who are…
By: Sayyed Hammad Ali
Tags: React, Leaflet, JavaScript, Maps, Tutorial

src/App.js

import React from 'react';

import MapView from './components/MapView';

import './App.css';function App() {

return (

<div className="App">

<MapView/>

</div>

);

}

export default App;

Link to File Source Code

This file is the starting point of the react app which imports the MapView.js component in the main application.

src/App.css

.leaflet-container { width: 100vw; height: 100vh; }

Link to File Source Code

The css file just sets the height and width of the leaflet container so it fills the viewport (vw: viewport-width, vh: viewport-height).

src/components/VenueLocationIcon.js

import L from 'leaflet';export const VenueLocationIcon = L.icon({

iconUrl: require('../assets/venue_location_icon.svg'),

iconRetinaUrl: require('../assets/venue_location_icon.svg'),

iconAnchor: null,

shadowUrl: null,

shadowSize: null,

shadowAnchor: null,

iconSize: [35, 35],

className: 'leaflet-venue-icon'

});

Link to File Source Code

This file creates an object for the custom marker icon for the leaflet map. In our case we use an svg file /src/assets/venue_location_icon.svg to create the VenueLocationIcon object for the map markers.

src/components/MapView.js

import React, { Component } from 'react';

import { Map, TileLayer } from 'react-leaflet';

import 'leaflet/dist/leaflet.css';

import data from '../assets/data';

import Markers from './VenueMarkers';class MapView extends Component {

constructor(props) {

super(props);

this.state = {

currentLocation: { lat: 52.52437, lng: 13.41053 },

zoom: 12,

}

}

render() {

const { currentLocation, zoom } = this.state;

return (

<Map center={currentLocation} zoom={zoom}>

<TileLayer

url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"

attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"

/> <Markers venues={data.venues}/>

</Map>

);

}

}

export default MapView;

Link to File Source Code

First we import the Map and TileLayer components from the react-leaflet package.

import { Map, TileLayer } from 'react-leaflet';

Then we import leaflet.css from the leaflet package.

import 'leaflet/dist/leaflet.css';

The /src/assets/data.json file containing venue information is then imported in the data variable. This contains venue name, description and geometry (coordinates: lat, long).

Link to data.json

import data from '../assets/data';

Import the Markers component (this will be explained later).

import Markers from './VenueMarkers';

The component state currentLocation contains fallback coordinates (Berlin lat, long). The zoom default value is set to 12. These settings will make the map center on Berlin with a zoom level of 12 on page load.

this.state = {

currentLocation: { lat: 52.52437, lng: 13.41053 },

zoom: 12,

}

In the render function the Map component is returned. This contains the center and zoom props which are set to currentLocation and zoom .

The TileLayer component adds the tiles for map. At the end we pass data.venues as props to the Markers component so all markers are displayed on the map.

return (

<Map center={currentLocation} zoom={zoom}>

<TileLayer

url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"

attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"

/>

<Markers venues={data.venues}/>

</Map>

);

src/components/VenueMarkers.js

import React, { Fragment } from 'react';

import {Marker} from 'react-leaflet';

import {VenueLocationIcon} from './VenueLocationIcon';

import MarkerPopup from './MarkerPopup'; const VenueMarkers = (props) => {

const { venues } = props;

const markers = venues.map((venue, index) => (

<Marker

key={index}

position={venue.geometry}

icon={VenueLocationIcon}

>

<MarkerPopup data={venue}/>

</Marker>

)); return <Fragment>{markers}</Fragment>};export default VenueMarkers;

Link to File Source Code

We import the Marker component from the react-leaflet package,

import {Marker} from 'react-leaflet';

the marker object that was created before to use the custom icon on the map,

import {VenueLocationIcon} from './VenueLocationIcon';

and import the MarkerPopup component (this will be explained below).

import MarkerPopup from './MarkerPopup';

In the react functional component VenueMarkers we get props (venues data) from the parent component MapView.js and save it in venues . We use the map function to create markers for each venue. We pass the position and the icon props to each Marker component so it contains the custom marker icon and the latitude and longitude from venue.geometry .

Inside each marker, we pass venue to the data props of the MarkerPopup component.

At the end we return all the markers . We use a fragment tag to wrap them together so we don’t add extra nodes to the DOM.

const { venues } = props;

const markers = venues.map((venue, index) => (

<Marker

key={index}

position={venue.geometry}

icon={VenueLocationIcon}

>

<MarkerPopup data={venue}/>

</Marker>

));

return <Fragment>{markers}</Fragment>};

export default VenueMarkers;

src/components/MarkerPopup.js

import React from 'react';

import {Popup} from 'react-leaflet';const MarkerPopup = (props) => {

const { name } = props.data;

return (

<Popup>

<div className='poup-text'>{name}</div>

</Popup>

);

};

export default MarkerPopup;

Link to File Source Code

We import the Popup component from the react-leaflet package.

import {Popup} from 'react-leaflet';

The MarkerPopup component just opens the popup when a marker is clicked on the map and it displays the venue name in the popup.