在 React 组件中使用 Google 映射
Using Google Map in React Component
我正在尝试在 React Component 中使用 Google Map,但它似乎不起作用。
我目前指的是 https://developers.google.com/maps/documentation/javascript/adding-a-google-map
这是我的组件代码:
class ContactBody extends React.Component {
componentWillMount() {
const script = document.createElement("script");
const API = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=initMap`;
script.async = true;
document.body.appendChild(script);
};
initMap() {
const uluru = {lat: -25.363, 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() {
this.initMap();
return (
<div>
<h1>Contact</h1>
<div id="map" style={{width: 400, height: 300}}></div>
</div>
)
}
}
ReactDOM.render(
<ContactBody />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
然而,当我 运行 这个时,我得到 "Uncaught ReferenceError: google is not defined"
有人能告诉我我的代码有什么问题吗?
谢谢。
您正在向文档添加 <script>
标记以加载 Google 地图 API,但您并未在 [=44= 之前等待它实际加载]宁你的 initMap
方法。由于尚未加载,google
变量尚不存在。
您已将参数添加到脚本的 URL、callback
,值为 initMap
。 Google 地图 API 将在准备就绪后看到此 运行 一个名为 initMap
的函数。但是 你的 initMap
方法在全局范围内不可用,因此不会 运行.
修复代码的一种方法是为 Google 地图 API 做出自己的承诺,并在 Google 地图的(全局)回调函数中解决该承诺API 可以 运行。在您的组件代码中,您将等待 promise 在继续之前得到解决。
可能看起来像这样:
class ContactBody extends React.Component {
getGoogleMaps() {
// If we haven't already defined the promise, define it
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 = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
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.getGoogleMaps();
}
componentDidMount() {
// Once the Google Maps API has finished loading, initialize the map
this.getGoogleMaps().then((google) => {
const uluru = {lat: -25.363, 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>
<h1>Contact</h1>
<div id="map" style={{width: 400, height: 300}}></div>
</div>
)
}
}
ReactDOM.render(
<ContactBody />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
我是这样做的:
import React from 'react';
export default class GoogleMap extends React.Component {
constructor(props) {
super(props);
this.state = {
mapIsReady: false,
};
}
componentDidMount() {
const ApiKey = 'XXXXXXXXXXXXXXXXXXXX';
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${ApiKey}`;
script.async = true;
script.defer = true;
script.addEventListener('load', () => {
this.setState({ mapIsReady: true });
});
document.body.appendChild(script);
}
componentDidUpdate() {
if (this.state.mapIsReady) {
// Display the map
this.map = new window.google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 12,
mapTypeId: 'roadmap',
});
// You also can add markers on the map below
}
}
render() {
return (
<div id="map" />
);
}
}
对于那些遇到错误的人 google is not defined 就在 eslint 提到的错误之上,继续定义
const google = window.google;
尝试在页面顶部键入此内容(对我有用)- /* global google */
如果您在 index.html 中包含 Google API 脚本,则有无需在 componentDidMount() 中 createElement。
你可以这样做-
import React from 'react';
export default class GoogleMap extends React.Component {
constructor(props) {
super(props);
this.state = {
mapIsReady: false,
};
}
componentDidMount() {
//Load Map after DOM is loaded
window.onload = this.setState({mapIsReady : true});
}
componentDidUpdate() {
if (this.state.mapIsReady) {
// Display the map
this.map = new window.google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 12,
mapTypeId: 'roadmap',
});
// You also can add markers on the map below
}
}
render() {
return (
<div id="map"></div>
);
}
}
将脚本添加到 head 标记(我的建议是 react-helmet)然后等于 window.initMap 到您的初始化映射函数,因为在脚本 src 中定义 (callback=initMap"
) 一个名为 'initMap'。
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
const Map = () => {
useEffect(() => {
window.initMap = () => {
new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
};
}, []);
return (
<>
<Helmet>
<script src="https://maps.googleapis.com/maps/api/js key=?key=YOUR_API_KEY&callback=initMap" async defer />
</Helmet>
<div style={{ height: "100%" }} id="map"></div>
</>
);
};
如果在服务器端呈现必须检查是在浏览器环境中,因为 window
在 node.js 环境中未定义:
... lang-js
if (process.browser) { // check browser environment
window.initMap = (): void => {
new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
};
}
...
在 React 应用中,
在 index.html 中使用脚本标签加载 google 地图 api 不工作,会给你错误 Access origin deny .....
解决方法是在下游模块系统中加载 google 映射 api,使用 useEffect() 挂钩。
例如,我简单地使用app.js加载api,你可以使用任何组件来这样做。不需要 app.js
这是我的工作代码:
import React, { useState, useEffect } from 'react';
function App() {
useEffect(() => {
const googleMapScript = document.createElement('script');
googleMapScript.src=`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLEMAPS_API_KEY}&libraries=places&callback=initMap`;
googleMapScript.async = true;
window.document.body.appendChild(googleMapScript);
});
return (
不要忘记将你的 google 地图 api 键放在 .env 文件中,
所以你可以将其称为
process.env.REACT_APP_GOOGLEMAPS_API_KEY
.env 文件应放在根文件夹中,与 package.json 所在的位置相同,因此 .env 文件应位于 package.json 文件旁边。
这是 .env 文件的样子:
REACT_APP_GOOGLEMAPS_API_KEY=AIzajfU2J8m4vE
记住,您的密钥必须以“REACT_APP_”开头,
我正在尝试在 React Component 中使用 Google Map,但它似乎不起作用。 我目前指的是 https://developers.google.com/maps/documentation/javascript/adding-a-google-map
这是我的组件代码:
class ContactBody extends React.Component {
componentWillMount() {
const script = document.createElement("script");
const API = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
script.src = `https://maps.googleapis.com/maps/api/js?key=${API}&callback=initMap`;
script.async = true;
document.body.appendChild(script);
};
initMap() {
const uluru = {lat: -25.363, 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() {
this.initMap();
return (
<div>
<h1>Contact</h1>
<div id="map" style={{width: 400, height: 300}}></div>
</div>
)
}
}
ReactDOM.render(
<ContactBody />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
然而,当我 运行 这个时,我得到 "Uncaught ReferenceError: google is not defined"
有人能告诉我我的代码有什么问题吗?
谢谢。
您正在向文档添加 <script>
标记以加载 Google 地图 API,但您并未在 [=44= 之前等待它实际加载]宁你的 initMap
方法。由于尚未加载,google
变量尚不存在。
您已将参数添加到脚本的 URL、callback
,值为 initMap
。 Google 地图 API 将在准备就绪后看到此 运行 一个名为 initMap
的函数。但是 你的 initMap
方法在全局范围内不可用,因此不会 运行.
修复代码的一种方法是为 Google 地图 API 做出自己的承诺,并在 Google 地图的(全局)回调函数中解决该承诺API 可以 运行。在您的组件代码中,您将等待 promise 在继续之前得到解决。
可能看起来像这样:
class ContactBody extends React.Component {
getGoogleMaps() {
// If we haven't already defined the promise, define it
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 = 'AIzaSyDbAz1XXxDoKSU2nZXec89rcHPxgkvVoiw';
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.getGoogleMaps();
}
componentDidMount() {
// Once the Google Maps API has finished loading, initialize the map
this.getGoogleMaps().then((google) => {
const uluru = {lat: -25.363, 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>
<h1>Contact</h1>
<div id="map" style={{width: 400, height: 300}}></div>
</div>
)
}
}
ReactDOM.render(
<ContactBody />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
我是这样做的:
import React from 'react';
export default class GoogleMap extends React.Component {
constructor(props) {
super(props);
this.state = {
mapIsReady: false,
};
}
componentDidMount() {
const ApiKey = 'XXXXXXXXXXXXXXXXXXXX';
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${ApiKey}`;
script.async = true;
script.defer = true;
script.addEventListener('load', () => {
this.setState({ mapIsReady: true });
});
document.body.appendChild(script);
}
componentDidUpdate() {
if (this.state.mapIsReady) {
// Display the map
this.map = new window.google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 12,
mapTypeId: 'roadmap',
});
// You also can add markers on the map below
}
}
render() {
return (
<div id="map" />
);
}
}
对于那些遇到错误的人 google is not defined 就在 eslint 提到的错误之上,继续定义
const google = window.google;
尝试在页面顶部键入此内容(对我有用)- /* global google */
如果您在 index.html 中包含 Google API 脚本,则有无需在 componentDidMount() 中 createElement。 你可以这样做-
import React from 'react';
export default class GoogleMap extends React.Component {
constructor(props) {
super(props);
this.state = {
mapIsReady: false,
};
}
componentDidMount() {
//Load Map after DOM is loaded
window.onload = this.setState({mapIsReady : true});
}
componentDidUpdate() {
if (this.state.mapIsReady) {
// Display the map
this.map = new window.google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 12,
mapTypeId: 'roadmap',
});
// You also can add markers on the map below
}
}
render() {
return (
<div id="map"></div>
);
}
}
将脚本添加到 head 标记(我的建议是 react-helmet)然后等于 window.initMap 到您的初始化映射函数,因为在脚本 src 中定义 (callback=initMap"
) 一个名为 'initMap'。
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
const Map = () => {
useEffect(() => {
window.initMap = () => {
new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
};
}, []);
return (
<>
<Helmet>
<script src="https://maps.googleapis.com/maps/api/js key=?key=YOUR_API_KEY&callback=initMap" async defer />
</Helmet>
<div style={{ height: "100%" }} id="map"></div>
</>
);
};
如果在服务器端呈现必须检查是在浏览器环境中,因为 window
在 node.js 环境中未定义:
... lang-js
if (process.browser) { // check browser environment
window.initMap = (): void => {
new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
};
}
...
在 React 应用中,
在 index.html 中使用脚本标签加载 google 地图 api 不工作,会给你错误 Access origin deny .....
解决方法是在下游模块系统中加载 google 映射 api,使用 useEffect() 挂钩。
例如,我简单地使用app.js加载api,你可以使用任何组件来这样做。不需要 app.js
这是我的工作代码:
import React, { useState, useEffect } from 'react';
function App() {
useEffect(() => {
const googleMapScript = document.createElement('script');
googleMapScript.src=`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLEMAPS_API_KEY}&libraries=places&callback=initMap`;
googleMapScript.async = true;
window.document.body.appendChild(googleMapScript);
});
return (
不要忘记将你的 google 地图 api 键放在 .env 文件中, 所以你可以将其称为
process.env.REACT_APP_GOOGLEMAPS_API_KEY
.env 文件应放在根文件夹中,与 package.json 所在的位置相同,因此 .env 文件应位于 package.json 文件旁边。
这是 .env 文件的样子:
REACT_APP_GOOGLEMAPS_API_KEY=AIzajfU2J8m4vE
记住,您的密钥必须以“REACT_APP_”开头,