6

The old way of doing things in react-leaflet 2.8.0 was to use MapLayer and withLeaflet.

But now in react-leaflet:

MapLayer and withLeaflet are deprecated as of version 3.

I'm trying to grasp the documentation for core: https://react-leaflet.js.org/docs/core-introduction

but the following doesn't work, I get

The provided object is not a Layer.

import React, { Component, useEffect } from "react";
import { useLeafletContext, leafletElement, createLayerComponent } from '@react-leaflet/core'
import { MapContainer, TileLayer, useMap } from "react-leaflet";
import Leaflet from "leaflet";
import "leaflet-routing-machine";

function Routing(props) {
    const context = useLeafletContext();
    useEffect(() => 
    {
      let routing = createLayerComponent(Leaflet.Routing.control(
      {
        waypoints: [
          Leaflet.latLng(33.52001088075479, 36.26829385757446),
          Leaflet.latLng(33.50546582848033, 36.29547681726967)
        ],
        lineOptions: {
          styles: [{ color: "#6FA1EC", weight: 4 }]
        },
        show: false,
        addWaypoints: false,
        routeWhileDragging: true,
        draggableWaypoints: true,
        fitSelectedRoutes: true,
        showAlternatives: false
      }), )
      const container = context.layerContainer || context.map
      container.addLayer(routing)

      return () => {
        container.removeLayer(routing)
      }
    })
  return null;
}


function MapComponent() {

  return (
      <MapContainer center={[33.5024, 36.2988]} zoom={14} >
        <TileLayer url="https://api.maptiler.com/maps/ch-swisstopo-lbm-dark/256/{z}/{x}/{y}.png?key=gR2UbhjBpXWL68Dc4a3f" />
        <Routing />
      </MapContainer>
    );
  }


export default MapComponent;

2 Answers 2

13

You're using createLayerComponent, but the routing machine is actually a control. Use createControlComponent.

I also recommend making this as a separate custom component, as described in the docs, rather than putting it in a useEffect. The docs are hard. Feel free to read How to extend TileLayer component in react-leaflet v3? to see if that helps in understanding how to make custom components with react-leaflet v3.

Here's how you'd do it:

import L from "leaflet";
import { createControlComponent } from "@react-leaflet/core";
import "leaflet-routing-machine";

const createRoutineMachineLayer = (props) => {
  const instance = L.Routing.control({
    waypoints: [
      L.latLng(33.52001088075479, 36.26829385757446),
      L.latLng(33.50546582848033, 36.29547681726967)
    ],
    ...otherOptions
  });

  return instance;
};

const RoutingMachine = createControlComponent(createRoutineMachineLayer);

export default RoutingMachine;

Working Codesandbox

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome answer Seth! really clear with a great working example and suggestions for improvement with references to other answers here on SO.
0

// Basic leaflet Routing Machine Code //

import React, { useEffect } from "react";
import { MapContainer, TileLayer, useMap } from "react-leaflet";
import "leaflet-routing-machine";
import L from "leaflet";
import "leaflet/dist/leaflet.css";

const Routing = ({ start, end }) => {
  const map = useMap();

  useEffect(() => {
    if (!map) return;

    // Create a routing control and add it to the map
    const routingControl = L.Routing.control({
      waypoints: [
        L.latLng(start.lat, start.lng),
        L.latLng(end.lat, end.lng),
      ],
      routeWhileDragging: true,
      lineOptions: {
        styles: [{ color: "#6FA1EC", weight: 4 }],
      },
    }).addTo(map);

    return () => {
      map.removeControl(routingControl);
    };
  }, [map, start, end]);

  return null;
};

const App = () => {
  const startPoint = { lat: 19.076, lng: 72.8777 }; // Example: Mumbai
  const endPoint = { lat: 18.5204, lng: 73.8567 }; // Example: Pune

  return (
    <MapContainer
      center={[19.076, 72.8777]}
      zoom={7}
      style={{ height: "100vh", width: "100%" }}
    >
      <TileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution="&copy; <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"
      />
      <Routing start={startPoint} end={endPoint} />
    </MapContainer>
  );
};

export default App;

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.