我正在尝试在需要时以编程方式添加Google api脚本。但是,我收到一个未定义google的错误消息。我可以看到该脚本是在body标签结尾之前添加的。
之前我已经在index.html文件中加载了脚本,但是现在我在应用程序的其他位置创建了一个不同的组件,该组件需要自己的脚本,因为它具有不同的api密钥。因此,我不得不从index.html中删除脚本,因为它为脚本的多次使用提供了例外。现在,我想在组件正在加载时添加它。
请参考以下代码获取主要组件:
import React from 'react';
import { Button } from 'reactstrap';
import CitySuggestionBar from './CitySuggestionBar';
export default class Destination extends React.Component{
componentDidMount(){
this.renderScript();
}
renderScript = () => {
loadScript('https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=places');
}
showPlaceDetails(place) {
let city = place.address_components[0].long_name.toString();
try{
city+= '+' + place.address_components[2].long_name.toString();
}catch(e){}
city = city.replace(/\s/g, "+");
sessionStorage.setItem('city', city);
console.log(city);
}
redirect = () =>{
sessionStorage.getItem('city') ? this.props.history.push("/hotels") : alert('Please select a city first');
}
render(){
return(
<div className="location-search-container">
<div className="location-search-wrapper">
<h1>Search for a city...</h1>
<CitySuggestionBar onPlaceChanged={this.showPlaceDetails.bind(this)} />
<Button onClick={this.redirect} className="btns" to="/hotels" color="primary">Proceed</Button>
</div>
</div>
);
}
}
const loadScript = (url) => {
const index = window.document.getElementsByTagName('script')[0];
const script = window.document.createElement('script');
script.src=url;
index.parentNode.insertBefore(script, index);
}
以下是正在使用google map的组件的代码,它是上述主要组件的子组件:
import React from "react";
/* global google */
export default class CitySuggestionBar extends React.Component {
constructor(props) {
super(props);
this.autocompleteInput = React.createRef();
this.autocomplete = null;
this.handlePlaceChanged = this.handlePlaceChanged.bind(this);
}
componentDidMount() {
this.autocomplete = new window.google.maps.places.Autocomplete(this.autocompleteInput.current,
{"types": ['(cities)']});
this.autocomplete.addListener('place_changed', this.handlePlaceChanged);
}
handlePlaceChanged(){
const place = this.autocomplete.getPlace();
this.props.onPlaceChanged(place);
}
render() {
return (
<input ref={this.autocompleteInput} id="autocomplete" placeholder="Search"
type="text"></input>
);
}
}
请帮助! 预先感谢。
答案 0 :(得分:0)
在上面的代码片段中,我可以看到,每次componentDidMount它将再次创建另一个脚本标签来避免这种情况时,您可以按以下方式修改loadScript方法:
const loadScript = (url) => {
const googleScript = window.document.getElementByClassName('google-script');
if (googleScript.length === 0) {
const script = window.document.createElement('script');
script.src=url;
script.class="google-script"
document.body.appendChild(script)
}
}
如果您想删除Google脚本,则可以在componentWillUnmount内部进行处理。
使用此方法不会显示脚本标记多次使用的例外情况。
如果您想知道是否已加载脚本标签,也可以通过在loadScript方法中添加另一个标签来找到它,如下所示:
const loadScript = (url) => {
const googleScript = window.document.getElementByClassName('google-script');
if (googleScript.length === 0) {
const script = window.document.createElement('script');
script.src=url;
script.class="google-script"
document.body.appendChild(script)
script.onload = () => {
// Place code here to do further action.
};
}
}
<----------------------------更新----------------- ---------->
为了解决“未定义google”错误,您可以尝试按照以下方法为Google Maps API创建承诺,并在可以运行Google Maps API的(全局)回调函数中解决该承诺。然后,在组件代码中,您将等待诺言得到解决,然后再继续。
const loadScript = () => {
if (!this.googleMapsPromise) {
this.googleMapsPromise = new Promise((resolve) => {
// Add a global handler for when the API finishes loading
window.resolveGoogleMapsPromise = () => {
// Resolve the promise
resolve(google);
// Tidy up
delete window.resolveGoogleMapsPromise;
};
// Load the Google Maps API
const script = document.createElement("script");
const API = //your api key;
script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=resolveGoogleMapsPromise`;
script.async = true;
document.body.appendChild(script);
});
}
// Return a promise for the Google Maps API
return this.googleMapsPromise;
}
componentWillMount() {
// Start Google Maps API loading since we know we'll soon need it
this.loadScript();
}
componentDidMount() {
// Once the Google Maps API has finished loading, initialize the map
this.getGoogleMaps().then((google) => {
const uluru = { lat: -25.366, lng: 131.044 };
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
const marker = new google.maps.Marker({
position: uluru,
map: map
});
});
}
render() {
return (
<div>
<div id="map" style={{width: 600, height: 300}}></div>
</div>
)
}