点击Google地图自带地标后自定义Marker的InfoWindow无法显示
解决Google地图点击原生地标后自定义Marker的InfoWindow无法显示问题
问题
从事件数据库生成自定义Marker,点击时会显示包含事件名称与描述的InfoWindow,但点击Google地图自带的地标(如埃菲尔铁塔这类POI)后,再点击自定义Marker,InfoWindow就不再显示,添加clickable属性也无改善。
原因
- 点击原生POI时,Google地图会自动弹出原生InfoWindow,干扰React组件的状态逻辑,导致后续自定义Marker的点击无法正确触发InfoWindow渲染。
- 原代码中
hasData的设置时机错误,异步数据还未加载完成就标记为有数据,可能引发Marker或InfoWindow的渲染异常。 - 未处理地图点击事件,无法在点击原生POI或空白区域时重置选中状态,导致状态残留。
修复后的代码
import React, { useEffect, useState } from 'react'; import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api'; import { getlocArray, retrieveListings } from './listings'; const containerStyle = { width: '600px', height: '600px', }; const center = { lat: 34.0703, lng: -118.448, }; function MapsComponent() { const [markers, setMarkers] = useState([]); const [selectedMarker, setSelectedMarker] = useState(null); const [listings, setListings] = useState([]); const [hasData, setHasData] = useState(false); useEffect(() => { async function fetchData() { try { const data = await retrieveListings(); setListings(data); const importedlocArray = await getlocArray(); if (importedlocArray.length > 0) { setMarkers( importedlocArray.map((location, index) => ({ key: index, position: { lat: location[1], lng: location[0], }, })) ); } // 数据加载完成后再标记为有数据 setHasData(true); } catch (err) { console.error('加载数据失败:', err); setHasData(true); // 即使加载失败也显示状态,可根据需求调整 } } fetchData(); }, []); const handleMarkerClick = (marker) => { setSelectedMarker(marker); }; const handleInfoWindowClose = () => { setSelectedMarker(null); }; // 点击地图(包括原生POI)时重置选中状态 const handleMapClick = () => { setSelectedMarker(null); }; return ( <> {hasData ? ( <LoadScript googleMapsApiKey="API-key"> <GoogleMap mapContainerStyle={containerStyle} center={center} zoom={15} onClick={handleMapClick} // 添加地图点击事件 > {markers.map((marker) => ( <Marker key={marker.key} position={marker.position} onClick={() => handleMarkerClick(marker)} /> ))} {selectedMarker && ( <InfoWindow position={selectedMarker.position} onCloseClick={handleInfoWindowClose} > <div> <h3>{listings[selectedMarker.key]?.title || '无标题'}</h3> <p>{listings[selectedMarker.key]?.description || '无描述'}</p> </div> </InfoWindow> )} </GoogleMap> </LoadScript> ) : ( <p>加载事件中...</p> )} </> ); } export default React.memo(MapsComponent);
关键修改点
- 将
setHasData(true)移到异步数据加载完成后,确保地图渲染时数据已准备就绪。 - 给
GoogleMap添加onClick事件,点击地图任意区域(包括原生POI)时重置selectedMarker,清除状态残留。 - 在InfoWindow的内容中添加可选链操作符
?.,避免因数据索引异常导致的渲染错误。 - 移除了不必要的
sleep函数,异步数据加载无需手动延迟。
内容的提问来源于stack exchange,提问作者Emily
相关产品推荐
相关产品推荐

