Google maps APIを使用して地図を表示したいのですが、index.htmlに入れるよりも<script>
タグを読み込む方が良い方法があるのではないかと思います。
/map
ルートに移動したときにのみスクリプトをロードしたいと思います。したがって、index.html
から削除して、動的にロードしたいと思います。ただし、すでにロードされている場合は、再度ロードしないようにする必要もあります。
これを処理するライブラリがあるかどうかはわかりません。私がこれまでに試した(しかし失敗した)のは、実際のdomに<script>
を追加し、それにキーを割り当てるloadScript
関数を作成することです。この場合、'google-maps
です。
ありがとう
2019年10月6日更新:サンプルコードは引き続き正常に機能しています。デコレータ以外の構文を使用するように更新しました。
これが私の最近のプロジェクトで機能させたものです。 react-async-script-loader コンポーネントを使用しました。
import React from 'react';
import scriptLoader from 'react-async-script-loader';
class Maps extends React.Component {
constructor(props) {
super(props);
this.map = null;
}
componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
if (isScriptLoaded && !this.props.isScriptLoaded) {
// load finished
if (isScriptLoadSucceed) {
this.map = new google.maps.Map(this.refs.map, {
center: { lat: 10.794234, lng: 106.706541 },
zoom: 20
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
position => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
this.map.setCenter(pos);
const marker = new google.maps.Marker({
position: pos,
map: this.map,
title: 'Hello World!'
});
},
() => {
console.log('navigator disabled');
}
);
} else {
// Browser doesn't support Geolocation
console.log('navigator disabled');
}
} else this.props.onError();
}
}
render() {
return (
<div>
<div ref="map" style={{ height: '80%', width: '100%' }}></div>
{!this.map && <div className="center-md">Loading...</div>}
</div>
);
}
}
export default scriptLoader(['https://maps.googleapis.com/maps/api/js?key=API_KEY'])(Maps);
ありがとう グエンタン 。 google
がグローバルスコープになっているので、window.google
を使用しました。
import React, { Component } from 'react';
import scriptLoader from 'react-async-script-loader';
class Map extends Component{
constructor(props) {
super(props);
}
componentWillReceiveProps({isScriptLoadSucceed}){
if (isScriptLoadSucceed) {
var markers = [];
var map = new window.google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {lat: 37.7749300, lng: -122.4194200}
});
}
else{
alert("script not loaded")
}
}
render(){
return(
<div>
<div id="map" style={{height: "600px"}}></div>
</div>
)
}
}
export default scriptLoader(
["https://maps.googleapis.com/maps/api/js?key= APIKEY"]
)(Map)
反応フックを使用すると、外部スクリプトをロードすることもできます
//useScript custom hooks from the site
let cachedScripts = [];
function useScript(src) {
// Keeping track of script loaded and error state
const [state, setState] = useState({
loaded: false,
error: false
});
useEffect(
() => {
// If cachedScripts array already includes src that means another instance ...
// ... of this hook already loaded this script, so no need to load again.
if (cachedScripts.includes(src)) {
setState({
loaded: true,
error: false
});
} else {
cachedScripts.Push(src);
// Create script
let script = document.createElement("script");
script.src = src;
script.async = true;
// Script event listener callbacks for load and error
const onScriptLoad = () => {
setState({
loaded: true,
error: false
});
};
const onScriptError = () => {
// Remove from cachedScripts we can try loading again
const index = cachedScripts.indexOf(src);
if (index >= 0) cachedScripts.splice(index, 1);
script.remove();
setState({
loaded: true,
error: true
});
};
script.addEventListener("load", onScriptLoad);
script.addEventListener("error", onScriptError);
// Add script to document body
document.body.appendChild(script);
// Remove event listeners on cleanup
return () => {
script.removeEventListener("load", onScriptLoad);
script.removeEventListener("error", onScriptError);
};
}
},
[src] // Only re-run effect if script src changes
);
return [state.loaded, state.error];
}
使用法
//App.js
import React from "react";
import ReactDOM from "react-dom";
import { useState, useEffect } from "react";
function App() {
const [loaded, error] = useScript(
"https://maps.googleapis.com/maps/api/js?key=API_KEY"
);
useEffect(() => {
if (loaded) {
new window.google.maps.Map(document.getElementById("map"), {
zoom: 12,
center: { lat: 37.77493, lng: -122.41942 }
});
}
}, [loaded]);
return (
<div>
<div>
Script loaded: <b>{loaded.toString()}</b>
</div>
<div id="map" style={{ height: "600px" }} />
</div>
);
}
さらに別のパッケージ react-dependent-script
package 次の機能を提供するGoogleマップライブラリをロードします。
これは簡単な例で、mapコンポーネントをReactDependentScript
コンポーネントでラップします。
<ReactDependentScript
scripts={[
"https://maps.googleapis.com/maps/api/js?key={YOUR-KEY-GOES-HERE}"
]}>
<Map center={{ lat: -34.397, lng: 150.644 }} zoom={3} />
</ReactDependentScript>
ここにデモがあります 参考のために