react-async-script 实现:包装一个组件
react-async-script implementation: wrapping a component
我正在尝试用 react-async-script
.
中的 makeAsyncScriptLoader
包装一个需要 google 映射 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 />
.
来从另一个文件调用该组件
基本上是行不通的。该组件尝试在没有脚本的情况下加载,但失败了。
根据 documentation 可以指定以下属性以确保 JavaScript 资源完成加载:
asyncScriptOnLoad
: function : called after script finishes loading.
using script.onload
或
callbackName
: string : If the script needs to call a global function
when finished loading (for example:
recaptcha/api.js?onload=callbackName). Please provide the callback
name here and it will be autoregistered on window for you.
对于 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 地图组件可以像这样呈现:
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);
我正在尝试用 react-async-script
.
makeAsyncScriptLoader
包装一个需要 google 映射 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 />
.
基本上是行不通的。该组件尝试在没有脚本的情况下加载,但失败了。
根据 documentation 可以指定以下属性以确保 JavaScript 资源完成加载:
asyncScriptOnLoad
: function : called after script finishes loading. using script.onload
或
callbackName
: string : If the script needs to call a global function when finished loading (for example: recaptcha/api.js?onload=callbackName). Please provide the callback name here and it will be autoregistered on window for you.
对于 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 地图组件可以像这样呈现:
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);