如何使用@react-google-maps/api为地图标记添加点击触发的信息提示框
使用@react-google-maps/api为标记添加点击弹出信息窗口
要实现点击标记弹出自定义信息窗口的功能,需要用到@react-google-maps/api提供的InfoWindow组件,以下是具体修改步骤:
1. 更新组件导入
在原导入语句中添加InfoWindow组件:
import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api';
2. 扩展标记数据结构
为了让标记携带信息窗口需要展示的内容,修改MapProps接口,给otherMarkers增加标题、描述字段:
export interface MapProps { isMarkerShown?: boolean; otherMarkers?: { lat: number; lng: number; title: string; // 信息窗口标题 description: string; // 信息窗口内容 }[]; lat: number; lng: number; }
3. 添加状态管理跟踪窗口状态
在组件内部用useState记录当前选中的标记,控制信息窗口的显示/隐藏:
import { useState } from 'react'; export const Map = ({ lat, lng, isMarkerShown = true, otherMarkers }: MapProps) => { const [selectedMarker, setSelectedMarker] = useState<typeof otherMarkers[0] | null>(null); // 关闭信息窗口的通用函数 const closeInfoWindow = () => setSelectedMarker(null); // 点击标记时打开对应窗口 const handleMarkerClick = (marker: typeof otherMarkers[0]) => { setSelectedMarker(marker); };
4. 绑定事件并渲染信息窗口
修改otherMarkers的渲染逻辑,给每个标记添加点击事件,并在选中时渲染对应的InfoWindow:
{otherMarkers && otherMarkers.map((marker) => ( <React.Fragment key={`${marker.lat}-${marker.lng}`}> <Marker title={marker.title} position={{ lat: marker.lat, lng: marker.lng }} icon="/assets/svg/MapMarkerRoundedIcon.svg" onClick={() => handleMarkerClick(marker)} /> {/* 仅当前标记被选中时显示窗口 */} {selectedMarker === marker && ( <InfoWindow position={{ lat: marker.lat, lng: marker.lng }} onCloseClick={closeInfoWindow} > <div style={{ padding: '8px', minWidth: '160px' }}> <h3 style={{ margin: '0 0 6px 0', fontSize: '14px' }}>{marker.title}</h3> <p style={{ margin: 0, fontSize: '12px', color: '#555' }}>{marker.description}</p> </div> </InfoWindow> )} </React.Fragment> ))}
完整修改后的代码
import { useState } from 'react'; import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api'; import { AppConfig } from '../../../constants/AppConfig'; const containerStyle = { width: '100%', height: '100%', }; export interface MapProps { isMarkerShown?: boolean; otherMarkers?: { lat: number; lng: number; title: string; description: string; }[]; lat: number; lng: number; } export const Map = ({ lat, lng, isMarkerShown = true, otherMarkers }: MapProps) => { const [selectedMarker, setSelectedMarker] = useState<typeof otherMarkers[0] | null>(null); const closeInfoWindow = () => setSelectedMarker(null); const handleMarkerClick = (marker: typeof otherMarkers[0]) => { setSelectedMarker(marker); }; return ( <LoadScript googleMapsApiKey={AppConfig.googleMapsApiKey}> <GoogleMap options={{ disableDefaultUI: true, styles: [ { featureType: 'poi', elementType: 'labels', stylers: [{ visibility: 'off' }] }, { featureType: 'transit', elementType: 'labels', stylers: [{ visibility: 'off' }] }, ], }} mapContainerStyle={containerStyle} center={{ lat, lng }} zoom={15} onClick={closeInfoWindow} // 点击地图空白处关闭窗口 > <Marker position={{ lat, lng }} visible={isMarkerShown} options={{}} icon="/assets/svg/MapMakerIcon.svg" /> {/* 带信息窗口的其他标记 */} {otherMarkers && otherMarkers.map((marker) => ( <React.Fragment key={`${marker.lat}-${marker.lng}`}> <Marker title={marker.title} position={{ lat: marker.lat, lng: marker.lng }} icon="/assets/svg/MapMarkerRoundedIcon.svg" onClick={() => handleMarkerClick(marker)} /> {selectedMarker === marker && ( <InfoWindow position={{ lat: marker.lat, lng: marker.lng }} onCloseClick={closeInfoWindow} > <div style={{ padding: '8px', minWidth: '160px' }}> <h3 style={{ margin: '0 0 6px 0', fontSize: '14px' }}>{marker.title}</h3> <p style={{ margin: 0, fontSize: '12px', color: '#555' }}>{marker.description}</p> </div> </InfoWindow> )} </React.Fragment> ))} </GoogleMap> </LoadScript> ); };
关键说明
- 点击标记时触发
handleMarkerClick,将当前标记设为选中状态,对应的信息窗口自动显示 - 点击信息窗口的关闭按钮或地图空白处,都会触发
closeInfoWindow关闭窗口 - 可以自定义
InfoWindow内部的HTML结构和样式,匹配你需要的视觉效果
内容的提问来源于stack exchange,提问作者Michael-Liendo
相关产品推荐
相关产品推荐

