useLeafletContext() can only be used in a descendant of <MapContainer>
Asked Answered
W

6

5

I am in the process of converting a leaflet-map in React into a hook with the use of react-leaflet and react-leaflet-markercluster. Everything worked perfectly except the use of the MarkerCluster component. The app gives this error: Error: No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>

I have tried to do the exact same thing as in this codesandbox, including using the same versions of the packages: https://codesandbox.io/s/9binx?file=/src/styles.scss:168-206

Both in the existing project and a completely fresh one (create-react-app). It still gives the same error in the existing project. So did the fresh project, but was fixed when removing this from the package.json:

    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]

This was never in the existing project though. Here is the package.json for the existing project:

{
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@reduxjs/toolkit": "1.4.0",
        "@sentry/react": "5.27.1",
        "@sentry/tracing": "5.27.1",
        "classnames": "^2.3.1",
        "http-proxy-middleware": "1.0.6",
        "leaflet": "^1.7.1",
        "leaflet.markercluster": "^1.5.1",
        "moment": "2.29.1",
        "normalize.css": "8.0.1",
        "rc-slider": "9.5.4",
        "react": "17.0.1",
        "react-app-polyfill": "2.0.0",
        "react-datepicker": "3.3.0",
        "react-dates": "21.8.0",
        "react-dom": "17.0.1",
        "react-html5-camera-photo": "1.5.4",
        "react-leaflet": "^3.2.1",
        "react-leaflet-markercluster": "^3.0.0-rc1",
        "react-markdown": "5.0.2",
        "react-query": "2.25.2",
        "react-redux": "7.2.2",
        "react-responsive-pinch-zoom-pan": "0.3.0",
        "react-router-dom": "4.3.1",
        "react-scripts": "4.0.0",
        "react-select": "3.1.0",
        "redux": "4.0.5",
        "redux-actions": "2.6.5",
        "redux-devtools-extension": "2.13.8",
        "redux-logger": "3.0.6",
        "redux-persist": "6.0.0",
        "redux-thunk": "2.3.0",
        "typescript": "4.0.5"
    },
    "scripts": {
        "start": "BROWSER=NONE REACT_APP_DISABLE_LIVE_RELOAD=false react-scripts start",
        "build": "react-scripts build",
        "build--withStats": "react-scripts build --stats",
        "test": "react-scripts test",
        "test:coverage": "npm run test -- --coverage",
        "eject": "react-scripts eject",
        "analyze": "source-map-explorer build/static/js/main.*"
    },
    "lint-staged": {
        "src/**/*.{js,jsx,ts,tsx,json,css}": [
            "prettier --single-quote --tab-width 4 --write"
        ]
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "eslintConfig": {
        "extends": [
            "react-app",
            "react-app/jest"
        ]
    },
    "proxy": "http://localhost:8080/",
    "devDependencies": {
        "@testing-library/dom": "7.26.3",
        "@testing-library/jest-dom": "5.11.5",
        "@testing-library/react": "11.1.0",
        "@testing-library/user-event": "12.1.10",
        "@tsconfig/recommended": "1.0.1",
        "@types/history": "4.7.2",
        "@types/jest": "26.0.15",
        "@types/leaflet": "^1.5.19",
        "@types/node": "14.14.5",
        "@types/react": "16.9.53",
        "@types/react-dom": "16.9.8",
        "@types/react-redux": "7.1.9",
        "@types/react-router-dom": "4.3.1",
        "@types/redux-logger": "3.0.8",
        "fetch-mock": "^9.10.7",
        "fetch-mock-jest": "^1.3.0",
        "husky": "4.3.0",
        "jest-environment-jsdom-sixteen": "1.0.3",
        "lint-staged": "10.5.0",
        "msw": "0.21.3",
        "prettier": "2.1.2",
        "source-map-explorer": "2.5.0"
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not op_mini all"
    ],
    "jest": {
        "collectCoverageFrom": [
            "src/**/*.{js,jsx,ts,tsx}",
            "!<rootDir>/node_modules/",
            "!<rootDir>/integration-tests/",
            "!<rootDir>/public/",
            "!<rootDir>/build/"
        ],
        "coverageThreshold": {
            "global": {
                "branches": 90,
                "functions": 90,
                "lines": 90,
                "statements": 90
            }
        },
        "coverageReporters": [
            "text"
        ]
    }
}

Anyone have any clue as to what it could be that's causing the error?

Whistling answered 29/9, 2021 at 6:15 Comment(2)
hello, is there any updates? did you solve this?Extended
Hi, no my team decided to abandon this and go for the classic leaflet js solution.Whistling
S
3

In the 3.2.0 release of react-leaflet, the author of the library started using the nullish coalescing operator which as I understand it breaks various bundlers including create-react-app when the MarkerCluster plugin pulls in the new react-leaflet as a peer dependency.

The CodeSandbox you linked is using version 3.0.2 and one fix is for you to use a react-leaflet version <3.2.0 in your package.json

"react-leaflet": ">=3.1.0 <3.2.0",
"@react-leaflet/core": ">=1.0.0 <1.1.0"  // you may not need this one

Of course this will prevent you from picking up updates in the future, so you will need to check the Github issues periodically and see if a fix has been released.

Significs answered 30/9, 2021 at 17:59 Comment(0)
C
1

I just got the same error message. In my case, there were multiple versions of @react-leaflet/core present in my project.

My yarn.lock file had 2 entries pointing to different versions:

"@react-leaflet/core@^1.0.2":
  version "1.1.0"
  ...

"@react-leaflet/core@^1.1.1":
  version "1.1.1"
  ...

I solved the issue by combining them into a single entry:

"@react-leaflet/core@^1.0.2", "@react-leaflet/core@^1.1.1":
  version "1.1.1"
  ...
Carden answered 19/1, 2022 at 10:57 Comment(0)
B
1

Instead of react.js wrappers you can use this.

import { FC, useRef, useEffect } from 'react'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
require('leaflet.markercluster/dist/leaflet.markercluster-src')

const Map: FC = () => {

    useEffect(() => {
        const map = L.map('map').setView([51.505, -0.09], 13)
        L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '© OpenStreetMap'
        }).addTo(map)

        const icon = L.icon({
            iconUrl: 'https://cdn-icons-png.flaticon.com/512/2776/2776067.png',
            iconSize: [30, 30]
        })

        const markers = L.markerClusterGroup()
        const marker = L.marker(new L.LatLng(38.423733, 27.142826), { icon })
        marker.bindPopup("<b>Hello world!</b><br>I am a popup.")
        const marker2 = L.marker(new L.LatLng(38.453899, 27.211700), { icon })
        markers.addLayer(marker)
        markers.addLayer(marker2)
        map.addLayer(markers)
        return () => {
            map.off()
            map.remove()
        }
    }, [])

    return <div id='map'></div>
}

export default Map
`
Bulldog answered 28/9, 2022 at 14:39 Comment(0)
T
1

Resolved the problem by removing react-leaflet-markercluster and installing @changey/react-leaflet-markercluster.

Tirzah answered 7/11, 2023 at 22:39 Comment(0)
F
0

This last works for me, I just walk back to a previous react-leaflet version and the useLeafletContext() works as well.

Feints answered 16/12, 2021 at 19:44 Comment(1)
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.Schecter
H
0

try npm i @react-leaflet/core

try npm install leaflet-draw

Humo answered 12/7, 2023 at 9:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.