React Leaflet Marker鼠标悬停切换图标问题求助
解决Leaflet Marker鼠标悬停切换图标的问题
问题根源分析
当前代码无法实现需求,主要有三个核心问题:
- 共享状态冲突:所有Marker共用同一个
isHovering状态,导致悬停任意一个Marker时,所有Marker都会切换图标 - 事件绑定错误:
event.target.handleIconSize()中的event.target是Leaflet的Marker实例,并非React组件实例,无法调用组件内的handleIconSize函数 - 冗余组件嵌套:Marker被不必要地包裹在
GeoJSON组件内,GeoJSON用于渲染地理数据图层,单独渲染Marker无需此嵌套
修正方案
直接通过Leaflet Marker实例的API切换图标,无需维护React状态,同时给每个Marker独立绑定事件:
const Layers = () => { const [geoJson, setgeoJson] = useState([data]); const iconSettings = { mapIconUrl: '<svg version="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 149 178"><path fill="{mapIconColor}" stroke="#FFF" stroke-width="6" stroke-miterlimit="10" d="M126 23l-6-6A69 69 0 0 0 74 1a69 69 0 0 0-51 22A70 70 0 0 0 1 74c0 21 7 38 22 52l43 47c6 6 11 6 16 0l48-51c12-13 18-29 18-48 0-20-8-37-22-51z"/><circle fill="{mapIconColorInnerCircle}" cx="74" cy="75" r="61"/><circle fill="#FFF" cx="74" cy="75" r="{pinInnerCircleRadius}"/></svg>', mapIconColor: "#7678a8", mapIconColorInnerCircle: "#fff", pinInnerCircleRadius: 48, }; // 普通状态图标 const divIcon = L.divIcon({ className: "leaflet-data-marker", html: L.Util.template(iconSettings.mapIconUrl, iconSettings), iconAnchor: [12, 32], iconSize: [25, 30], popupAnchor: [0, -28], }); // 悬停状态图标 const divIconActive = L.divIcon({ className: "leaflet-data-marker", html: L.Util.template(iconSettings.mapIconUrl, iconSettings), iconAnchor: [18, 42], iconSize: [40, 42], popupAnchor: [0, -30], }); const getMarkerPosition = (city) => { switch (city) { case "Växjö": return [56.8787183, 14.8094385]; case "Sundsvall": return [62.40766, 16.93196]; case "Lund": return [55.42, 13.1124]; default: return; } }; return ( <> {geoJson[0].features.map((item) => { const city = item.properties.display_name; return ( <Marker key={city} position={getMarkerPosition(city)} icon={divIcon} onMouseOver={(e) => e.target.setIcon(divIconActive)} onMouseOut={(e) => e.target.setIcon(divIcon)} > <Popup>{city}</Popup> </Marker> ); })} </> ); }; export default Layers;
关键修改点说明
- 移除冗余嵌套:删除不必要的
LayerGroup和GeoJSON组件,直接渲染Marker - 独立事件处理:给每个Marker绑定
onMouseOver和onMouseOut事件,通过Leaflet实例的setIcon方法直接切换图标,无需React状态 - 添加key属性:在map循环中给Marker添加唯一
key,符合React列表渲染规范 - 简化状态逻辑:去掉全局的
isHovering状态,避免多Marker状态冲突
Map组件无需修改,保持原代码即可
内容的提问来源于stack exchange,提问作者Lillviking
相关产品推荐
相关产品推荐

