React集成@googlemaps/markerclusterer缩放时集群显示异常
解决React中@googlemaps/markerclusterer缩放时集群共存的问题
问题根源
每次地图边界变化(缩放触发)时,你在useEffect里重新创建了标记点和MarkerClusterer实例,但旧的标记和集群并没有从地图上移除,导致新老实例同时存在,出现不同层级集群共存的异常。
解决方案
1. 用useRef保存标记和集群实例
通过useRef存储标记数组和MarkerClusterer实例,方便在后续渲染时清理旧资源。
2. 添加清理逻辑
在useEffect的清理函数中,遍历标记数组移除每个标记,同时销毁旧的MarkerClusterer实例,避免残留。
3. 优化依赖项
确保useEffect的依赖项仅包含必要的变量(比如地图实例、地址列表、地图边界参数),避免不必要的重复渲染。
完整代码示例
import { useEffect, useRef } from 'react'; import { MarkerClusterer } from '@googlemaps/markerclusterer'; const MapComponent = ({ map, addresses, mapParams }) => { // 保存标记数组和集群实例的ref const markersRef = useRef([]); const clustererRef = useRef(null); useEffect(() => { // 清理旧的标记和集群 if (markersRef.current.length > 0) { markersRef.current.forEach(marker => marker.setMap(null)); markersRef.current = []; } if (clustererRef.current) { clustererRef.current.clearMarkers(); clustererRef.current = null; } // 创建新标记 const markers = addresses.map(address => { // 替换为你的地址转经纬度逻辑 const latLng = /* 经纬度转换代码 */; return new window.google.maps.Marker({ position: latLng, map: map }); }); // 创建集群器 const clusterer = new MarkerClusterer({ map: map, markers: markers, // 自定义集群图标路径(可根据需求修改) imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m' }); // 更新ref存储当前实例 markersRef.current = markers; clustererRef.current = clusterer; // 组件卸载或依赖变化时执行清理 return () => { markers.forEach(marker => marker.setMap(null)); if (clusterer) clusterer.clearMarkers(); }; }, [map, addresses, mapParams]); return null; }; export default MapComponent;
关键说明
- 每次
useEffect执行前先清空旧资源,确保地图上只有当前渲染的标记和集群。 - 使用
setMap(null)移除标记,调用clearMarkers()销毁集群内标记,避免内存泄漏和界面异常。 - 若地址列表不会频繁变化,可将地址转经纬度的逻辑抽离,减少重复计算开销。
内容的提问来源于stack exchange,提问作者Alexey Zalyotov
相关产品推荐
相关产品推荐

