react-leaflet-markercluster
react-leaflet-markercluster copied to clipboard
Compatibility issue with leaflet v4 and React 18?
I receive error that react-leaflet-markercluster is trying to use version 17 of react. leaflet v4 requires React 18.
I'm having the same issue. Fresh project with simple sample code, will give me console errors.
<MapContainer
className="map-container"
center={[49.8397, 24.0297]}
zoom={6}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MarkerClusterGroup>
<Marker position={[49.8397, 24.0297]} />
<Marker position={[52.2297, 21.0122]} />
<Marker position={[51.5074, -0.0901]} />
</MarkerClusterGroup>
</MapContainer>
are you getting "invalid hook call" as well? and does it run if you remove the MarkerClusterGroup component?
Yea, I was getting that. Removing MarkerClusterGroup
removed the errors. I was able to bypass these errors by downgrading to React 17 and react-leaflet v3.2.5.
haha, i did the same thing! ^^
Yea, I was getting that. Removing
MarkerClusterGroup
removed the errors. I was able to bypass these errors by downgrading to React 17 and react-leaflet v3.2.5.
Did the same thing as you did, but still getting: Error: No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>
can you share me your package.json file??
When will be fixed ? I need leaflet v4 and marker clustering
I'd also need this component to be compatible with react 18 and react-leaflet 4 and to be usable with GeoJson :)
Also need this component to be compatible with react 18 and react-leaflet 4. I'm appreciated for looking into the issue
This library is actually a pretty thin wrapper around leaflet.markercluster
: I got it working after
-
npm install leaflet.markercluster
that and then - gently converted the current react-leaflet-markercluster.js to this, in
components/MakeClusterGroup.ts
(just remove the handful of type definitions to convert to JS):
import 'leaflet.markercluster';
import {createPathComponent} from '@react-leaflet/core';
import L from 'leaflet';
const MarkerClusterGroup = createPathComponent(({children: _c, ...props}, ctx) => {
const clusterProps: Record<string, any> = {};
const clusterEvents: Record < string, any >= {};
// Splitting props and events to different objects
Object.entries(props).forEach(([propName, prop]) => propName.startsWith('on') ? (clusterEvents[propName] = prop)
: (clusterProps[propName] = prop));
// Creating markerClusterGroup Leaflet element
const markerClusterGroup = L.markerClusterGroup(clusterProps);
// Initializing event listeners
Object.entries(clusterEvents).forEach(([eventAsProp, callback]) => {
const clusterEvent = `cluster${eventAsProp.substring(2).toLowerCase()}`;
markerClusterGroup.on(clusterEvent, callback);
});
return {
instance: markerClusterGroup,
context: {...ctx, layerContainer: markerClusterGroup},
};
});
export default MarkerClusterGroup;
Then here's my full components/myMap.tsx
for completeness:
import "leaflet/dist/leaflet.css";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";
import MarkerClusterGroup from "./MarkerClusterGroup";
interface MapStationsProps {
latlons: [number, number][];
}
function MapStations({ latlons }: MapStationsProps) {
const position = [51.505, -0.09] as [number, number];
return (
<MapContainer
center={position}
zoom={5}
style={{ width: "100%", height: "600px" }}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
<MarkerClusterGroup> // <-------------------------------------- !
{latlons.map((v, i) => (
<Marker key={i} position={v} />
))}
</MarkerClusterGroup> // <-------------------------------------- !
</MapContainer>
);
}
export default MapStations;
Working with
"dependencies": {
"leaflet": "^1.8.0",
"leaflet.markercluster": "^1.5.3",
"next": "^12.1.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.0.0",
},
maybe one can try https://www.npmjs.com/package/@changey/react-leaflet-markercluster for react 18 and leaflet v4 compatibility for now
maybe one can try https://www.npmjs.com/package/@changey/react-leaflet-markercluster for react 18 and leaflet v4 compatibility for now
Does it support GeoJeson instead of Markers? Thanks!
maybe one can try https://www.npmjs.com/package/@changey/react-leaflet-markercluster for react 18 and leaflet v4 compatibility for now
Do you also have @ŧypes for this?
maybe one can try https://www.npmjs.com/package/@changey/react-leaflet-markercluster for react 18 and leaflet v4 compatibility for now
Does it support GeoJeson instead of Markers? Thanks!
Supports
[with reach 18, leaflet 1.8 and react-leaflet 4] Tried to wrap my geoJson in marker cluster like:
<MarkerClusterGroup>
<GeoJSON data={agentData} ref={geoJsonLayerRef} onEachFeature={visualData} />
</MarkerClusterGroup>
but I'm getting the "Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component." error. The code is inside a functional component, and the same error is thrown if I use three mock markers instead of the geojson. Any idea? I can't see which hook rules I'm breaking...
[with reach 18, leaflet 1.8 and react-leaflet 4] Tried to wrap my geoJson in marker cluster like:
<MarkerClusterGroup> <GeoJSON data={agentData} ref={geoJsonLayerRef} onEachFeature={visualData} /> </MarkerClusterGroup>
but I'm getting the "Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component." error. The code is inside a functional component, and the same error is thrown if I use three mock markers instead of the geojson. Any idea? I can't see which hook rules I'm breaking...
Maybe your issue is related with this issue https://github.com/PaulLeCam/react-leaflet/issues/897 I think my issue above is related too
https://github.com/changey/react-leaflet-markercluster works fine for me 🎉
[with reach 18, leaflet 1.8 and react-leaflet 4] Tried to wrap my geoJson in marker cluster like:
<MarkerClusterGroup> <GeoJSON data={agentData} ref={geoJsonLayerRef} onEachFeature={visualData} /> </MarkerClusterGroup>
but I'm getting the "Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component." error. The code is inside a functional component, and the same error is thrown if I use three mock markers instead of the geojson. Any idea? I can't see which hook rules I'm breaking...
Maybe your issue is related with this issue PaulLeCam/react-leaflet#897 I think my issue above is related too
Sorry I'm a newbie in react, javascript, leaflet and so on and can't follow the details of the issue discussion. I've tried with the minimal example but couldn't get it to work... I'm not using hooks, so what could be the problem?
@FabrizioPe The problem is that react-leaflet-markercluster provokes that hooks error when used with the newest versions of leaflet and react-leaflet. It is not your code.
You have two possible solutions:
- Use https://github.com/changey/react-leaflet-markercluster by installing
yarn add @changey/react-leaflet-markercluster
ornpm install @changey/react-leaflet-markercluster
instead ofreact-leaflet-markercluster
. You can then switch back toreact-leaflet-markercluster
itself once it has solved this issue. - Use the previous versions of leaflet (1.7.1) and react-leaflet (3.2.5). They work well with the current version of react-leaflet-markercluster
@FabrizioPe The problem is that react-leaflet-markercluster provokes that hooks error when used with the newest versions of leaflet and react-leaflet. It is not your code.
You have two possible solutions:
- Use https://github.com/changey/react-leaflet-markercluster by installing
yarn add @changey/react-leaflet-markercluster
ornpm install @changey/react-leaflet-markercluster
instead ofreact-leaflet-markercluster
. You can then switch back toreact-leaflet-markercluster
itself once it has solved this issue.- Use the previous versions of leaflet (1.7.1) and react-leaflet (3.2.5). They work well with the current version of react-leaflet-markercluster
Thanks @barbalex for your simple explanation! I'll try the new package asap :)
This issue sounds like it should be fixed with the code provided in this pull request or changey's release which incorporated my work to fix compatibily issues with Leaflet 4, React 18 and NextJS 12.