React集成Google Maps API报已加载错误排查方案
Google Maps API 加载报错
google api is already presented 排查与修复 相关参考信息
- 谷歌地图加载状态及报错信息截图
- React应用MapScreen文件截图
- 项目代码仓库
问题相关代码
库配置定义:
const libs = ['places'];
地图组件核心渲染逻辑:
return ( <div className="full-box"> <LoadScript libraries={libs} googleMapsApiKey={googleApiKey}> <GoogleMap id="smaple-map" mapContainerStyle={{ height: '100%', width: '100%' }} center={center} zoom={15} onLoad={onLoad} onIdle={onIdle} > <StandaloneSearchBox onLoad={onLoadPlaces} onPlacesChanged={onPlacesChanged} > <div className="map-input-box"> <input type="text" placeholder="Enter your address"></input> <Button type="button" onClick={onConfirm}> Confirm </Button> </div> </StandaloneSearchBox> <Marker position={location} onLoad={onMarkerLoad}></Marker> </GoogleMap> </LoadScript> </div> );
问题描述
电商应用集成Google Maps API时,触发google api is already presented报错。已知该报错通常由页面存在多个LoadScript标签重复加载API导致,但全应用排查后确认仅使用了一个LoadScript标签,常规排查方案无法解决问题。
排查方向
- 检查React 18+严格模式影响
React 18及以上版本的严格模式在开发环境会执行两次组件挂载/卸载流程,@react-google-maps/api旧版本的LoadScript组件首次挂载注入API脚本后,卸载阶段未正确清理全局window.google对象标记,第二次挂载时检测到全局已存在Google API对象就会抛出该错误。可临时关闭入口文件的React.StrictMode包裹验证,刷新页面后如果报错消失即可确认是该问题。 - 检查非组件形式的脚本注入
排查public目录下的入口html文件、全局路由守卫、通用布局组件,确认没有手动通过原生<script>标签引入Google Maps JS,同时排查项目引入的第三方依赖(如地址自动填充插件、定位插件)是否存在隐式注入Google Maps脚本的行为。可打开浏览器开发者工具的元素面板,搜索maps.googleapis.com关键字统计页面加载的Google Maps脚本数量,数量大于1即存在非LoadScript注入的脚本。 - 检查路由缓存带来的重复挂载
如果项目使用了路由缓存能力(如路由keepalive、组件缓存插件),离开地图页面时组件不会被真正卸载,重新进入页面时会再次触发LoadScript的加载逻辑,触发重复加载检测。
修复方案
- 针对严格模式导致的问题
优先升级@react-google-maps/api到最新稳定版,新版本已修复严格模式下重复加载的判断逻辑;如果暂时无法升级依赖,可直接使用包提供的LoadScriptNext组件替代原有LoadScript组件,该版本对脚本加载状态的管理更严谨,可正确处理全局google对象的状态判断,替换方式如下:// 原有引入方式 // import { LoadScript } from '@react-google-maps/api'; // 替换为 import { LoadScriptNext as LoadScript } from '@react-google-maps/api'; - 针对额外脚本注入问题
删除所有手动引入的Google Maps脚本标签,全应用统一通过LoadScript组件管理API加载,所有调用Google Maps能力的位置需保证传入的API key、依赖库列表、版本号参数完全一致,避免参数不一致触发重复加载判定。 - 针对组件缓存导致的问题
将LoadScript组件上移到应用根组件或全局公共布局层,仅在应用初始化时加载一次Google Maps API,业务地图页面内直接使用GoogleMap、StandaloneSearchBox等子组件即可,无需在每个业务页面单独嵌套LoadScript。
内容的提问来源于stack exchange,提问作者Oliver Cronk
相关产品推荐
相关产品推荐

