Задержка реакции компонента на нагрузку до загрузки скрипта головы шлема
У меня есть компонент реагирования, который опирается на Google Maps JS API. Это импортируется в заголовок страницы App.js с тегом script. Когда я пытаюсь загрузить страницу, содержащую этот компонент, происходит сбой, утверждая, что скрипт не загружен. Однако если я сначала открою другую страницу (которая приводит к загрузке сценария, но не включает этот компонент), а затем перейду к странице, содержащей компонент, это работает.
Это наводит меня на мысль, что проблема в том, что скрипт еще не загружен при загрузке компонента. Я думал, однако, что загрузка страницы должна блокироваться, пока она получает скрипт. Я не совсем уверен, как это исправить.
App.js:
class App extends Component {
render() {
return (
<Router>
<div>
<Helmet>
<script
type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDSn_vNbNZzrcFxl8bV3MH1j0kuoLVsOCQ&libraries=places"
/>
</Helmet>
<div className="pageContent">
<Route exact path="/foo" component={FooScreen} />
<Route exact path="/bar" component={BarScreen} /
</div>
</div>
</Router>
);
}
}
export default App;
Выше FooScreen содержит компонент, а BarScreen - нет. Если я открою FooScreen напрямую, произойдет сбой, если я открою BarScreen, а затем перейду к FooScreen, он будет работать.
1 ответ
Обычно прослушиватели событий должны быть присоединены к экземпляру элемента скрипта, например, к загрузчику скриптов на основе обещаний.
Этот случай специфичен для Google Maps или других сценариев, которые имеют процедуру асинхронной инициализации и принимают обратный вызов, поэтому слушать излишне load
событие:
state = { mapLoaded: false };
componentDidMount() {
window.onGoogleMap = () => this.setState({ mapLoaded: true });
}
componentWillUnmount() {
delete window.onGoogleMap;
}
render() {
return <>
<Helmet>
<script
type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=...&libraries=places&callback=onGoogleMap"
/>
</Helmet>
{!this.state.mapLoaded ? (
'Loading...'
) : (
<Router>...</Router>
)}
</>;
}
Поскольку глобальная переменная используется, для этого требуется не более одного экземпляра App
существовать одновременно, включая тесты.