由于react-leaflet,我目前正在显示带有GeoJSON组件的Map。我还在悬停在某些国家/地区上显示一些工具提示(例如,当我将鼠标悬停在法国时,工具提示显示为“法国”)。我也正在使用i18n进行国际化。问题是,当我切换语言时,它适用于整个页面,但不适用于这些工具提示。
我认为问题出在onEachFeature函数上,该函数在创建JSX Element GeoJSON时仅被调用一次,因此在切换语言时它不会更新。我认为是这样,因为工具提示在显示时是正确的语言(如果最初将语言设置为法语,则工具提示将使用法语,如果将语言设置为英语,则将它们设置为英语)。但是,当我们在GeoJSON组件初始化后更改语言时,它们根本不会更新。
我希望我已经说清楚了>
这是我的界面:
interface position { latlng: LatLngLiteral, tooltip: string } interface state { markers: position[], zoom: number, display: position[] | any, geoJson: any, countries: { [key: string]: position } }
这里是我组件的开头:
// t is the translation function, that should translate in the selected language. It is dynamic, it means that when we switch languages, it automatically update the translated string const { t }: { t: TFunction } = useTranslation(); const countryToString = (countries: string[]): string => countries.join(", "); // List of position and label of tooltip for the GeoJson object, for each country const countries: { [key: string]: position } = { DEU: { latlng: { lat: 51.0834196, lng: 10.4234469, }, tooltip: countryToString([ t("travel.germany.munich"), t("travel.germany.berlin"), t("travel.germany.hamburg"), t("travel.germany.munster"), t("travel.germany.country"), ]) }, CZE: { latlng: { lat: 49.667628, lng: 15.326962, }, tooltip: countryToString([ t("travel.tchequie.prague"), t("travel.tchequie.country"), ]) }, ... } // List of position and tooltip for the cities Markers const cities: position[] = [ { latlng: { lat: 48.13825988769531, lng: 11.584508895874023, }, tooltip: t("travel.germany.munich"), }, { latlng: { lat: 52.51763153076172, lng: 13.40965747833252, }, tooltip: t("travel.germany.berlin"), }, ...
[我有一个国家列表,这要归功于GeoJSON组件,我要显示一个城市列表,而这要归功于我通过Marker列表来显示的。
然后是功能部分:
// Contains the json containing the polygons of the countries const data: geojson.FeatureCollection = geoJsonData as geojson.FeatureCollection; let geoJson: any = <GeoJSON key='my-geojson' data={data} style={() => ({ color: '#4a83ec', weight: 1, fillColor: "#1a1d62", fillOpacity: 0.25, })} // PROBLEM : does not update the tooltips when we switch languages // FIX ME onEachFeature={(feature: geojson.Feature<geojson.GeometryObject>, layer: Layer) => { layer.on({ 'mouseover': (e: LeafletMouseEvent) => { const country = state.countries[e.target.feature.properties.adm0_a3]; layer.bindTooltip(country.tooltip); layer.openTooltip(country.latlng); }, 'mouseout': () => { layer.unbindTooltip(); layer.closeTooltip(); }, }); }} /> const [state, setState] = useState<state>({ markers: cities, zoom: 3, geoJson: geoJson, display: geoJson, countries: countries }); // 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 (state.markers.map( ( c: position, i: number ) => { return ( <Marker key={c.latlng.lat + c.latlng.lng} position={c.latlng}> <Tooltip>{c.tooltip}</Tooltip> </Marker> ); } )); } else { return state.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> );
[如果您想查看整个代码,则可以在此处看到:
https://github.com/TheTisiboth/WebCV/blob/WIP/src/components/customMap.tsx
由于react-leaflet,我目前正在显示带有GeoJSON组件的Map。我还在悬停在某些国家/地区上显示一些工具提示(例如,当我将鼠标悬停在法国时,工具提示显示为“ ...
显然,该插件无法处理以"travel.italy.roma, travel.italy.naples, travel.italy.pompei, travel.italy.country
形式连接的多个连接字符串,而且更重要的是,您似乎需要将函数调用放置在标记中(不是100%确定为什么原因,我不熟悉此插件-也许还有其他选择。
<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.markers.map(
(c: position, i: number): ReactElement => {
if (state.zoom >= 5) {
return (
<Marker key={i} position={[c.lat, c.lon]}>
<Tooltip>{t(c.tooltip)}</Tooltip>
</Marker>
);
} else {
return (
<CircleMarker
key={i}
center={[c.lat, c.lon]}
color='red'
radius={state.radius}
>
<Tooltip>{t(c.tooltip)}</Tooltip>
</CircleMarker>
);
}
}
)}
</Map>