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
相关产品推荐
相关产品推荐

