You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-google-maps点击Marker或关闭InfoWindow时地图重置问题求解

问题根因

你遇到的地图重置问题核心原因有两个:

  • <GoogleMap>组件绑定的center属性是固定的常量defaultCenter,每次selected状态更新触发组件重渲染时,地图中心点就会被强制重置为初始坐标
  • 地图渲染逻辑封装在组件内部的renderMap函数中,每次组件重渲染都会重新生成该函数,引发不必要的地图重绘

修复步骤

  1. 将固定常量移到组件外部,避免重复初始化
  2. 新增受控状态存储地图当前中心点,绑定到<GoogleMap>的center属性
  3. 监听地图中心点变更事件,实时更新受控状态
  4. 移除不必要的renderMap封装,直接返回JSX结构
  5. 给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 02:06:03