升级React-map-gl后use-supercluster的clusters数组为空
问题根因
clusters返回空完全是边界参数传递失效导致的,代码里存在两个核心逻辑问题:
bounds是组件渲染时直接计算的普通变量,首次渲染阶段地图DOM还没挂载,mapRef.current为空,bounds初始值为null;后续地图加载完成、用户拖动/缩放地图时,不会触发bounds重新计算,useSupercluster始终拿不到当前视口的有效经纬度边界,自然返回空数组。- 没有绑定地图的
onLoad生命周期,新版react-map-gl(v7+版本)ref的挂载时机和旧版有差异,即使地图渲染完成,也不会自动触发重渲染更新bounds值。
另外聚合点击缩放逻辑还有两个隐性bug:flyTo方法里的参数把center拼成了cener,且没有导入FlyToInterpolator,就算聚合显示出来点击也会报错。
修复方案
- 把bounds改为响应式state,新增边界更新方法,在地图加载、移动时同步更新bounds值
// 替换原来的普通bounds变量定义 const [bounds, setBounds] = React.useState(null); // 新增边界更新方法 const updateMapBounds = () => { if (!mapRef.current) return; const currentBounds = mapRef.current.getMap().getBounds().toArray().flat(); setBounds(currentBounds); };
- 给Map组件绑定
onLoad事件,同时修改原有onMove逻辑,保证视口变化时bounds能同步更新
<Map initialViewState={{...viewport}} mapStyle={process.env.REACT_APP_MAPBOX_STYLE_URL} mapboxAccessToken={process.env.REACT_APP_MAPBOX_ACCESS_TOKEN} onLoad={updateMapBounds} // 首次加载完成后更新初始边界 onMove={(e) => { setViewport(e.viewState); updateMapBounds(); // 缩放、拖动时同步更新边界 }} onClick={() => setSelectedHotel(null)} style={{width: "100%", height: "100%"}} ref={mapRef} > {/* 内部Marker、控件逻辑保持不变 */} </Map>
- 修复聚合点击缩放的逻辑错误,去掉冗余的viewport重复设置,直接调用map实例的flyTo方法即可,不需要额外导入插值器
const clusterZoom = (clusterID, latitude, longitude) => { const expansionZoom = Math.min( supercluster.getClusterExpansionZoom(clusterID), 20 ); mapRef.current?.flyTo({ center: [longitude, latitude], // 修复拼写错误 zoom: expansionZoom, duration: 2000 }); };
注意:useSupercluster配置里设置了
minPoints: 9,代表视口内至少9个点才会生成聚合簇,如果测试阶段点位数量不足,可以先把这个值调低(比如设为2),功能验证正常后再调整为业务需要的阈值。
改完之后刷新页面,首次加载、拖动缩放地图时clusters就会正常返回聚合簇和点位数据了。
内容的提问来源于stack exchange,提问作者User1990
相关产品推荐
相关产品推荐

