React集成Google Maps并添加SearchBox报错:google未定义求解决
嘿,我来帮你搞定这个问题!你遇到的google is not defined错误,本质是Google Maps的JS脚本还没加载完成,或者你的组件没正确等待脚本加载就调用了google全局对象。结合你用的react-google-maps库,我给你一步步梳理需要补全的内容:
1. 必须正确配置Google Maps脚本加载参数
withScriptjs这个高阶组件的核心作用就是帮你自动加载Google Maps脚本,但你得给它提供带API密钥和必要库的完整脚本URL——尤其是SearchBox依赖的places库,一定要加进去!
你需要在withProps里补充这几个关键配置:
withProps({ // 替换成你自己的Google Cloud API密钥,记得去后台启用Maps JS API和Places API googleMapURL: "https://maps.googleapis.com/maps/api/js?key=你的API_KEY&libraries=places", // 脚本加载时的占位元素 loadingElement: <div style={{ height: "100%" }}>加载中...</div>, // 地图容器的样式,必须设置高度才能显示 containerElement: <div style={{ height: "500px" }} />, // 地图本身的元素容器 mapElement: <div style={{ height: "100%" }} />, })
2. 组件嵌套顺序绝对不能错
react-google-maps的高阶组件有固定的嵌套顺序,最外层是withScriptjs,然后是withGoogleMap,最后才是你的地图组件。而且SearchBox必须放在GoogleMap组件内部,这样才能确保它能访问到已加载的google对象:
完整的组件结构示例:
const _ = require("lodash"); const { compose, withProps, lifecycle } = require("recompose"); const { withScriptjs, withGoogleMap, GoogleMap, SearchBox } = require("react-google-maps"); const MapWithSearchBox = compose( withProps({ googleMapURL: "https://maps.googleapis.com/maps/api/js?key=你的API_KEY&libraries=places", loadingElement: <div style={{ height: "100%" }} />, containerElement: <div style={{ height: "500px" }} />, mapElement: <div style={{ height: "100%" }} />, }), withScriptjs, withGoogleMap, lifecycle({ componentDidMount() { // 这里可以安全使用google对象,因为withScriptjs已经确保脚本加载完成 const autocomplete = new google.maps.places.Autocomplete(this.props.searchBoxRef.current.getInputElement()); // 监听地点选择事件 autocomplete.addListener("place_changed", () => { const place = autocomplete.getPlace(); // 比如把地图中心移到选中的地点 this.props.googleMap.setCenter(place.geometry.location); this.props.googleMap.setZoom(12); }); } }) )(props => ( <GoogleMap defaultCenter={{ lat: 39.9042, lng: 116.4074 }} // 默认北京坐标 defaultZoom={10} > {/* SearchBox要放在GoogleMap内部,通过ref获取输入框元素 */} <SearchBox ref={ref => (props.searchBoxRef = ref)} placeholder="搜索地点" controlPosition={google.maps.ControlPosition.TOP_LEFT} /> </GoogleMap> ));
3. 绝对不要在脚本加载前调用google对象
如果你在withScriptjs包裹的组件外部直接用google,或者在组件的早期生命周期(比如componentWillMount)里调用,肯定会报错——因为脚本还没加载完成。withScriptjs会自动等待脚本加载完毕后才渲染内部的withGoogleMap组件,所以所有依赖google的代码都要放在withGoogleMap包裹的组件里,或者像上面那样放在componentDidMount生命周期里。
4. 检查你的API密钥权限
最后别忘了去Google Cloud控制台,确保你的API密钥已经启用了Maps JavaScript API和Places API——如果权限没开,即使脚本加载了,SearchBox也无法正常工作,甚至会间接导致google对象相关功能报错。
内容的提问来源于stack exchange,提问作者Stacy Areas

