The other day I updated my application to React18 and found that something has changed there in the behavior of react-leaflet. In my project I wrote a custom wrapper for the leaflet-geocoder, which is then used in the MapContainer
Geocoder:
export const Geocoder: FC<{}> = props => {
//#region --Constants--
const map: L.Map = useMap();
const {t, i18n} = useTranslation();
//#endregion
//#region --States--
//#endregion
//#region --Hooks--
useEffect(() => {
Initialize();
}, []);
//#endregion
//#region --Functions--
const Initialize = (): void => {
const controller: MapController = new MapController();
const geocoderControl: GeocoderControl = geocoder({
geocoder: geocoders.mapbox({
apiKey: controller.Token,
geocodingQueryParams: {
language: i18n.language
}
}),
defaultMarkGeocode: false,
placeholder: t("search"),
errorMessage: t("noResult")
});
geocoderControl.on("markgeocode", result => {
const codingResult: GeocodingResult = result.geocode ?? result;
map.fitBounds(codingResult.bbox);
const newPopup: L.Popup = popup()
.setLatLng(codingResult.bbox.getCenter())
.setContent(codingResult.html ?? codingResult.name)
.openOn(map);
});
geocoderControl.addTo(map);
};
//#endregiony
//#region --Render--
return null;
//#endregion
};
Usage in the MapContainer of React-Leaflet:
<MapContainer center={props.latLng ?? defaultPosition} zoom={13} scrollWheelZoom={true}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url={mapController.BaseUrl}
accessToken={mapController.Token}
id={eLayer.STREETS}
/>
{
props.enableGeoCoding ?
<Geocoder/>
: null
}
<Markers latLng={props.latLng} fieldSetter={props.fieldSetter}/>
</MapContainer>
With the 17 version of React, it all worked and gave the following result:
Which is correct, the map shows only one geocoder. But now in React18 it looks like this:
After that I created a profile with the react-devtools and looked there why this renders again, the result was that the useMap()
hook inside the GeoCoder wrapper seems to change.
Do you know why this hook seems to change since the 18 version, code-wise nothing has changed in my code between React17 and 18.
This can be fixed by saving a reference to the geocoder, and deleting the control from the map when cleaning up the hook