我正在尝试使用makeAsyncScriptLoader
中的react-async-script
包装需要Google Maps api的react组件。
在同一文件中(如果有所不同):
class SearchBar extends Component {
/* Some stuff requiring the maps api */
}
const callbackName = "onloadcallback";
const URL = `https://maps.googleapis.com/maps/api/js?key=AIzaSyDSn_vNbNZzrcFxl8bV3MH1j0kuoLVsOCQ&callback=${callbackName}`;
const globalName = "foo";
export default makeAsyncScriptLoader(URL, {
callbackName: callbackName,
globalName: globalName
})(SearchBar);
我的理解是,我应该能够通过从上述文件中导入SearchBarWrapper
并将其用作<SearchBarWrapper />
来从另一个文件中调用该组件。
基本上,它不起作用。该组件尝试在没有脚本的情况下加载,并且失败。
答案 0 :(得分:0)
根据documentation,可以指定以下属性以确保JavaScript资源加载完成:
asyncScriptOnLoad
:函数:脚本加载完成后调用。 使用script.onload
或
callbackName
:字符串:如果脚本需要调用全局函数 完成加载后(例如: recaptcha / api.js?onload = callbackName)。请提供回调 在这里命名,它将自动在窗口中为您注册。
对于asyncScriptOnLoad
事件,可以引入以下HOC以确保在加载JavaScript资源后呈现包装的组件:
function withScript(url, WrappedComponent) {
const LoadingElement = props => {
return <div>Loading...</div>;
}
class Wrapper extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
scriptLoaded: false
};
}
render() {
const AsyncScriptLoader = makeAsyncScriptLoader(url)(LoadingElement);
if(this.state.scriptLoaded){
return <WrappedComponent/>
}
return (
<AsyncScriptLoader
asyncScriptOnLoad={() => {
this.setState({scriptLoaded: true});
}}
/>
);
}
}
return Wrapper;
}
现在Google Maps组件可以这样呈现:
const GoogleMapsUrl = `https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyDurZQBXjtSzKeieXwtFeGe-jhZu-HEGQU`;
const App = withScript(GoogleMapsUrl, Autocomplete);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);