react-google-maps多信息窗口无法传递marker id及弹窗异常求助
我帮你搞定这个问题!你遇到的情况其实是很典型的React状态管理问题——如果用单一的布尔值(比如isOpen)控制所有信息窗口的显示,那点击任意一个marker时,所有窗口都会跟着弹出。咱们换个思路,用状态跟踪当前具体哪个marker被激活,就能精准控制单个窗口的显示啦。
核心解决方案:用状态存储激活的Marker ID
我们不再用全局的布尔值,而是用状态保存当前点击的marker的唯一ID(或唯一标识),然后让每个InfoWindow只在自己对应的marker ID和激活ID匹配时才显示。
函数组件(React Hooks)示例
这是现在React更常用的写法,代码清晰简洁:
import { useState } from 'react'; import { GoogleMap, Marker, InfoWindow } from 'react-google-maps'; function MapWithMarkers() { // 用状态存储当前激活的marker ID,初始为null(没有窗口打开) const [activeMarkerId, setActiveMarkerId] = useState(null); // 假设你的marker数据数组,每个item要有唯一id、坐标和其他信息 const markers = [ { id: 1, position: { lat: 40.7128, lng: -74.0060 }, title: '纽约地标' }, { id: 2, position: { lat: 34.0522, lng: -118.2437 }, title: '洛杉矶地标' }, { id: 3, position: { lat: 37.7749, lng: -122.4194 }, title: '旧金山地标' }, ]; // 处理marker点击:如果点击的是当前激活的marker,就关闭窗口;否则激活它 const handleMarkerClick = (markerId) => { setActiveMarkerId(prevId => prevId === markerId ? null : markerId); }; // 关闭信息窗口时重置激活状态 const handleInfoWindowClose = () => { setActiveMarkerId(null); }; return ( <GoogleMap defaultZoom={8} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}> {markers.map(marker => ( <Marker key={marker.id} // 必须用唯一id作为key,别用数组索引(索引不稳定) position={marker.position} onClick={() => handleMarkerClick(marker.id)} > {/* 只有当前激活的marker对应的窗口才显示 */} <InfoWindow visible={activeMarkerId === marker.id} onCloseClick={handleInfoWindowClose} > <div> <h3>{marker.title}</h3> {/* 这里可以放更多marker的自定义内容 */} </div> </InfoWindow> </Marker> ))} </GoogleMap> ); }
类组件示例(如果还在用类组件的话)
import React from 'react'; import { GoogleMap, Marker, InfoWindow } from 'react-google-maps'; class MapWithMarkers extends React.Component { state = { activeMarkerId: null, }; markers = [ { id: 1, position: { lat: 40.7128, lng: -74.0060 }, title: '纽约地标' }, { id: 2, position: { lat: 34.0522, lng: -118.2437 }, title: '洛杉矶地标' }, ]; handleMarkerClick = (markerId) => { this.setState(prevState => ({ activeMarkerId: prevState.activeMarkerId === markerId ? null : markerId, })); }; handleInfoWindowClose = () => { this.setState({ activeMarkerId: null }); }; render() { return ( <GoogleMap defaultZoom={8} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}> {this.markers.map(marker => ( <Marker key={marker.id} position={marker.position} onClick={() => this.handleMarkerClick(marker.id)} > <InfoWindow visible={this.state.activeMarkerId === marker.id} onCloseClick={this.handleInfoWindowClose} > <div> <h3>{marker.title}</h3> </div> </InfoWindow> </Marker> ))} </GoogleMap> ); } }
为什么之前传递索引无效?
如果之前尝试用数组索引作为标识,可能是因为数组的索引不稳定(比如数组排序、增删元素时,索引会变化),导致React无法正确识别每个marker的唯一性。所以尽量用marker自带的唯一ID(比如后端返回的id)作为标识,而不是数组索引。
内容的提问来源于stack exchange,提问作者karl
相关产品推荐
相关产品推荐

