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?

2
  • hello, is there any updates? did you solve this?
    – Firas SCMP
    Commented Jan 13, 2022 at 10:57
  • 1
    Hi, no my team decided to abandon this and go for the classic leaflet js solution.
    – julziemoon
    Commented Jan 14, 2022 at 11:31

6 Answers 6

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.

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"
  ...
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
`
1

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

0
0

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

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.
    – Community Bot
    Commented Dec 17, 2021 at 2:56
0

try npm i @react-leaflet/core

try npm install leaflet-draw

Not the answer you're looking for? Browse other questions tagged or ask your own question.