react-google-maps点击Marker或关闭InfoWindow时地图重置问题求解
问题根因
你遇到的地图重置问题核心原因有两个:
<GoogleMap>组件绑定的center属性是固定的常量defaultCenter,每次selected状态更新触发组件重渲染时,地图中心点就会被强制重置为初始坐标- 地图渲染逻辑封装在组件内部的
renderMap函数中,每次组件重渲染都会重新生成该函数,引发不必要的地图重绘
修复步骤
- 将固定常量移到组件外部,避免重复初始化
- 新增受控状态存储地图当前中心点,绑定到
<GoogleMap>的center属性 - 监听地图中心点变更事件,实时更新受控状态
- 移除不必要的
renderMap封装,直接返回JSX结构 - 给Marker添加唯一key属性,避免React列表渲染警告
修正后完整代码
import React, {useState, useCallback} from 'react'; import {Marker, GoogleMap, LoadScript, InfoWindow} from '@react-google-maps/api'; // 常量移到组件外部,避免每次渲染重复创建 const mapStyles = { height: "100vh", width: "100%", } const defaultCenter = { lat: 45.510440, lng: -122.683338 } const MapContainer = ({markers}) => { const [selected, setSelected] = useState<any>({}) // 存储地图实例 const [mapInstance, setMapInstance] = useState<google.maps.Map | null>(null) // 新增受控状态存储地图当前中心点 const [center, setCenter] = useState(defaultCenter) const onSelect = (item) => { setSelected(item) // 如果需要点击Marker时自动定位到Marker位置,可以取消下方注释 // setCenter({lat: item.lat, lng: item.lng}) } // 地图加载完成后存储实例 const handleMapLoad = useCallback((map: google.maps.Map) => { setMapInstance(map) }, []) // 监听地图中心点变更,更新状态 const handleCenterChange = useCallback(() => { if (!mapInstance) return const currentCenter = mapInstance.getCenter() if (currentCenter) { setCenter({ lat: currentCenter.lat(), lng: currentCenter.lng() }) } }, [mapInstance]) return ( <div> <LoadScript googleMapsApiKey='[GOOGLE API KEY]'> <GoogleMap mapContainerStyle={mapStyles} zoom={13} {/* 绑定受控的center状态,而不是固定的defaultCenter */} center={center} onLoad={handleMapLoad} onCenterChanged={handleCenterChange} > {markers.map((marker)=> { return( <Marker key={marker.id ?? `${marker.lat}-${marker.lng}`} position={{ lat: marker.lat, lng: marker.lng }} title={marker.title} onClick={ () => onSelect(marker) } /> )}) } { selected.lng && <InfoWindow position={{ lat: selected.lat, lng: selected.lng }} onCloseClick={() => setSelected({})} > <div> <h3>{selected.title}</h3> <p>{selected.info}</p> </div> </InfoWindow> } </GoogleMap> </LoadScript> </div> ) } export default MapContainer;
内容的提问来源于stack exchange,提问作者Forrest Daggett
相关产品推荐
相关产品推荐

