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

Viewed 2869

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?

3 Answers

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.

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

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"
  ...
Related