如何解决使用 React Typescript 在 react-leaflet-markerclusterer 中显示所有集群标记
我的 React Typescript 应用使用 react-leaflet
和 react-leaflet-markerclusterer
显示带有标记簇的传单地图。
但是,我无法让地图显示地图视图内的所有集群标记。我正在尝试 convert this JS solution 打字稿。
中显示的错误之一。 JS控制台是
React Hook "useMap" 不能在回调中调用。 React Hooks 必须在 React 函数组件或自定义 React Hook 函数中调用
在 VSCode 中,还有一个 Typescript 错误
对象可能是“未定义”.ts(2532)
上线
const groupBounds = group.getBounds();
为什么会发生这种情况,编写此 Typescript 代码的正确方法是什么?
import React,{ useEffect,useRef } from 'react';
import { MapContainer,TileLayer,Marker,useMap } from 'react-leaflet';
import MarkerClusterGroup from 'react-leaflet-markercluster';
interface IProps {
markers: {
lat: number;
lon: number;
}[];
mapCenter: {
lat: number;
lon: number;
};
}
export function MapView({markers,mapCenter}: IProps): JSX.Element {
const groupRef = useRef();
useEffect(() => {
if (groupRef !== undefined) {
const group = groupRef.current;
const map = useMap(); // ERROR: React Hook "useMap" cannot be called inside a callback.
const groupBounds = group.getBounds(); // ERROR: Object is possibly 'undefined'.ts(2532)
map.fitBounds(groupBounds);
}
},[]);
return (
<MapContainer
center={[mapCenter.lat,mapCenter.lon]}
zoom={10}
style={{ width:'100%',height:'100vh' }}
className='markercluster-map'
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=${access_token}`}
/>
<MarkerClusterGroup ref={groupRef}>
{
markers.map((marker,index) => (
<Marker
position={[marker.lat,marker.lon]}
key={index}
/>
))
}
</MarkerClusterGroup>
</MapContainer>
)
}
解决方法
这不是打字稿问题,这是反应问题。钩 need to be called either within the top level of the function body,or as part of another custom hook。这同样适用于 react-leaflet 的 useMap
。您可以将其移到 useEffect
之外。但是,useMap
钩子调用必须是作为 MapContainer
子代的组件的一部分,以便它可以访问传单上下文对象。您可以将此逻辑抽象到它自己的组件中,例如在 this example 中,但我认为您最好使用带有状态变量的 whenCreated
来获取 L.Map
的实例并使用它的效果:
export function MapView({markers,mapCenter}: IProps): JSX.Element {
const groupRef = useRef();
const [map,setMap] = useState();
useEffect(() => {
if (groupRef && map) {
const group = groupRef.current;
const groupBounds = group?.getBounds();
map.fitBounds(groupBounds);
}
},[map,groupRef]);
return (
<MapContainer
whenCreated={map => setMap(map)}
moreProps={moreProps}
>
<Stuff />
</MapContainer>
)
}
如果 TS 仍然抱怨 group
或 map
未定义,您可以对它们使用可选的属性运算符 ?.
:
if (groupRef && map) {
const group = groupRef?.current;
const groupBounds = group?.getBounds();
map?.fitBounds(groupBounds);
}
Typescript 应该足够聪明,知道定义了 groupRef
和 map
,因为它们在 if
语句中,但它可能仍然抱怨 group
定义。您也可以执行 if (groupRef && groupRef.current && map)
以消除所有疑问。
**注意:确保您使用的是与 react-leaflet v3 兼容的正确 version of react-leaflet-markercluster。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。