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

React集成@google-maps-api刷新报错:Cannot read properties of undefined (reading 'maps')

问题分析与解决方案

错误原因

刷新页面时抛出Cannot read properties of undefined (reading 'maps'),核心原因是Google Maps JavaScript API尚未完成加载,组件就尝试访问google.maps对象(具体是在handleOnLoad函数中创建google.maps.LatLngBounds实例时)。首次加载正常是因为API在组件挂载前已加载完成,但刷新时组件可能先于API渲染,导致google对象未定义。

解决方案

方案1:使用useLoadScript确保API加载完成

@react-google-maps/api提供的useLoadScript钩子可监听API加载状态,仅在API就绪后渲染地图组件,这是最可靠的解决方式:

修改后的完整代码:

import { GoogleMap, MarkerF, InfoWindowF, useLoadScript } from '@react-google-maps/api';
import { useState } from 'react';

function Map() {
  const markers = [
    { id: 1, name: "Chicago, Illinois", position: { lat: 41.881832, lng: -87.623177 } },
    { id: 2, name: "Denver, Colorado", position: { lat: 39.739235, lng: -104.99025 } },
    { id: 3, name: "Los Angeles, California", position: { lat: 34.052235, lng: -118.243683 } },
    { id: 4, name: "New York, New York", position: { lat: 40.712776, lng: -74.005974 } }
  ];

  const [activeMarker, setActiveMarker] = useState(null);
  // 替换为你的Google Maps API密钥
  const { isLoaded, loadError } = useLoadScript({
    googleMapsApiKey: 'YOUR_API_KEY',
  });

  if (loadError) return <div>地图加载失败</div>;
  if (!isLoaded) return <div>加载中...</div>;

  const handleActiveMarker = (marker) => {
    if (marker === activeMarker) return;
    setActiveMarker(marker);
  };

  const handleOnLoad = (map) => {
    const bounds = new google.maps.LatLngBounds();
    markers.forEach(({ position }) => bounds.extend(position));
    map.fitBounds(bounds);
  };

  return (
    <div>
      <GoogleMap 
        onLoad={handleOnLoad} 
        onClick={() => setActiveMarker(null)} 
        mapContainerClassName="map-container"
        // 设置默认中心和缩放,避免加载时空白
        center={{ lat: 39.8283, lng: -98.5795 }}
        zoom={4}
      >
        {markers.map(({ id, name, position }) => (
          <MarkerF
            key={id}
            position={position}
            icon="http://maps.google.com/mapfiles/ms/icons/blue-dot.png"
            onClick={() => handleActiveMarker(id)}
          >
            {activeMarker === id && (
              <InfoWindowF onCloseClick={() => setActiveMarker(null)}>
                <div>{name}</div>
              </InfoWindowF>
            )}
          </MarkerF>
        ))}
      </GoogleMap>
    </div>
  );
}

export default Map;

方案2:添加安全判断(临时修复)

如果不想引入useLoadScript,可在访问google.maps前添加判断,避免直接访问未定义的对象:

修改handleOnLoad函数:

const handleOnLoad = (map) => {
  if (!google?.maps) return; // 新增安全判断
  const bounds = new google.maps.LatLngBounds();
  markers.forEach(({ position }) => bounds.extend(position));
  map.fitBounds(bounds);
};

但这种方式无法解决地图组件本身依赖API的问题,仅能避免报错,推荐优先使用方案1。

额外优化点

  • 将{activeMarker === id ? (...) : null}简化为{activeMarker === id && (...)},代码更简洁
  • 为GoogleMap组件添加默认center和zoom属性,避免API加载完成后地图短暂空白

内容的提问来源于stack exchange,提问作者Rayner Susanto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:45:44