Site icon Mobile App Development Services

Leaflet: An Alternative to React Google Maps with Search Functionality

For quite some time, I have been looking for a free and open-source alternative to Google map, because it started showing me the following issues:

Troubleshooters:

Then I came across Leaflet,

Leaflet is an open-source JavaScript library for creating mobile-friendly interactive maps, small and easy-to-use, in general, an amazing alternative to react-google-maps.

The level of control over Leaflet is unmatched, with an ever-growing collection of plugins and constantly updated, developer-driven API.

Reasons for selecting Leaflet:

  1. Easy to implement with few dependencies.
  2. Large community.
  3. customizable.

Steps for development

I would like to show you a simple and easy app using Create React App. (For instructions on how to get started, use the Quick Guide) and react-leaflet in just 3 steps. Leaflet tutorials are also available at egghead.io.

1. let’s install leaflet and react-leaflet. In the project directory, run:

npm install leaflet react-leaflet # for npm
yarn add leaflet react-leaflet # for yarn

2. Now, install esri-leaflet-geocoder to add search functionality in your map:

npm install esri-leaflet-geocoder # for npm
yarn add esri-leaflet-geocoder # for yarn

3. Create a Map component

/** @format */

import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import React, { useEffect, useState, useRef } from "react";
import { geosearch } from "esri-leaflet-geocoder";
import "leaflet/dist/leaflet.css";
import "esri-leaflet-geocoder/dist/esri-leaflet-geocoder.css";
import L from "leaflet";

function MapView(props) {
  const mapRef = useRef();
  const [position, setPosition] = useState([50, 10]);
  const [icon, setIcon] = useState();

  useEffect(() => {
    const { current = {} } = mapRef;
    const { leafletElement: map } = current;

    if (!map) return;

    const control = geosearch();

    control.addTo(map);

    control.on("results", handleOnSearchResuts);

    let greenIcon = L.icon({
      iconUrl:
        "https://upload.wikimedia.org/wikipedia/commons/c/c9/Font_Awesome_5_solid_map-marker-alt.svg",
      shadowUrl:
        "https://upload.wikimedia.org/wikipedia/commons/c/c9/Font_Awesome_5_solid_map-marker-alt.svg",
      iconSize: [20, 30],
      // iconAnchor: [22, 94],
      // popupAnchor: [-3, -76],
      shadowSize: [20, 30],
      // shadowAnchor: [22, 94],
    });
    setIcon(greenIcon);

    return () => {
      control.off("results", handleOnSearchResuts);
    };
  }, []);

  /**
   * handleOnSearchResuts
   * @param {object} data Results object from esri-leaflet-geocoder
   */

  const handleOnSearchResuts = (data) => {
    console.log("Search results", data);
    setPosition([data.latlng.lat, data.latlng.lng]);
  }
  return (
    <Map
      ref={mapRef}
      center={position}
      zoom={6}
      style={{ width: "400px", height: "400px" }}
    >
      <TileLayer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png" />
      <Marker position={position} icon={icon}>
        <Popup>Popup for any custom information.</Popup>
      </Marker>
    </Map>
  );
}

export default MapView;

Tadaa… Our Map is all set to work

Have I missed something? Please feel free to post in the comments.