I am currently displaying a Map, thanks to react-leaflet, with a GeoJSON Component. I'm also displaying some tooltips on hover over some countries and cities(for example, when I hover France, a tooltip display "France"). I'm also using i18n for internationalization. The internationalization works fine for the country tooltips, they are updated in real time.
I have a function updateDisplay
, that switch between a GeoJson component for the countries, or a list of Marker for the cities, on zoom change.
The problem is, that when i'm switching languages, it works fine for the whole page, but not for the city tooltips. They are updated only when I zoom (so when the updateDisplay is called).
I would have the expected behaviour : regardless of the zoom, I would like that the city tooltips update in real time, when i switch language.
I hope I've made myself clear
Here is my code :
/**
* Display a Leaflet Map, containing a GeoJson object, or a list of Markers, depending on the zoom
*/
export default function CustomMap(): ReactElement {
const { t }: { t: TFunction } = useTranslation();
const countryToString = (countries: string[]): string => countries.map(c => t(c)).join(", ");
// Contains the json containing the polygons of the countries
const data: geojson.FeatureCollection = geoJsonData as geojson.FeatureCollection;
let geoJson: JSX.Element = <GeoJSON
key='my-geojson'
data={data}
style={() => ({
color: '#4a83ec',
weight: 1,
fillColor: "#1a1d62",
fillOpacity: 0.25,
})}
onEachFeature={(feature: geojson.Feature<geojson.GeometryObject>, layer: Layer) => {
layer.on({
'mouseover': (e: LeafletMouseEvent) => {
const country = countries[e.target.feature.properties.adm0_a3];
layer.bindTooltip(countryToString(country.tooltip as string[]));
layer.openTooltip(country.latlng);
},
'mouseout': () => {
layer.unbindTooltip();
layer.closeTooltip();
},
});
}}
/>
// Contains a list of marker for the cities
const cityMarkers: JSX.Element[] = cities.map(
(
c: position,
i: number
) => {
return (
// Here are the tooltips that doesn't update in real time, when we switch language
// FIX ME
<Marker key={c.latlng.lat + c.latlng.lng} position={c.latlng}>
<Tooltip>{t(c.tooltip as string)}</Tooltip>
</Marker>
);
}
);
const [state, setState] = useState<state>({
zoom: 3,
display: geoJson,
});
// Update on zoom change
function onZoom(e: LeafletMouseEvent): void {
const zoom = e.target._zoom;
const newDisplay = updateDisplay(zoom);
setState({
...state,
zoom,
display: newDisplay,
});
}
// Called on every zoom change, in order to display either the GeoJson, or the cities Marker
function updateDisplay(zoom: number): Marker[] | any {
if (zoom >= 4) {
return cityMarkers;
} else {
return geoJson;
}
}
return (
<Map
style={{ height: "500px" }}
center={[54.370138916189596, -29.918133437500003]}
zoom={state.zoom}
onZoomend={onZoom}
>
<TileLayer url="https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw" />
{state.display}
</Map>
);
}
You can also look at it here : https://github.com/TheTisiboth/WebCV/blob/WIP/src/components/customMap.tsx
It is on the branch WIP