react集成钉钉api
介绍 (Introduction)
This tutorial aims at integrating the google maps API to your React components and enabling you to display maps on your website.
本教程旨在将google maps API集成到您的React组件中,并使您能够在网站上显示地图。
先决条件 (Prerequisites)
设置一个React应用 (Setting Up a React Application)
For a quick setup, we are going to use Facebook’s create-react-app repository as base.
为了快速设置,我们将使用Facebook的create-react-app存储库作为基础。
To obtain that demo code, run:
要获取该演示代码,请运行:
- npm i -g create-react-app npm i -g创建React应用
- create-react-app my-googlemap create-react-app my-googlemap
- cd my-googlemap cd my-googlemap
Before we add any code, let’s install our dependencies with:
在添加任何代码之前,让我们使用以下命令安装依赖项:
- npm install --save google-maps-react npm install-保存谷歌地图React
Now edit our src
folder and remove files and imports that are unnecessary:
现在,编辑我们的src
文件夹,并删除不必要的文件和导入:
logo.svg
logo.svg
App.css
App.css
index.css
index.css
In
index.js
remove the css import.在
index.js
删除css导入。
创建一个组件 (Creating a Component)
We’ll need to edit our App.js
file and instead have our component that will load our google map.
我们需要编辑App.js
文件,而要使用我们的组件来加载Google地图。
import React, { Component } from 'react';
import { Map, GoogleApiWrapper } from 'google-maps-react';
const mapStyles = {
width: '100%',
height: '100%'
};
export class MapContainer extends Component {
render() {
return (
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{
lat: -1.2884,
lng: 36.8233
}}
/>
);
}
}
export default GoogleApiWrapper({
apiKey: 'YOUR_GOOGLE_API_KEY_GOES_HERE'
})(MapContainer);
For a basic Google Map, this is literally all the code you need. Go ahead and run your app and ensure that the map loads to the browser.
对于基本的Google Map,这实际上就是您需要的所有代码。 继续并运行您的应用程序,并确保将地图加载到浏览器。
The Map component takes in some optional props such as style(the CSS style object), Zoom(number value representing a tighter focus on the map’s center) and initialCenter(an object containing latitude and longitude coordinates)
Map组件带有一些可选的道具,例如style(CSS样式对象),Zoom(表示在地图中心的焦点的数字值)和initialCenter(包含纬度和经度坐标的对象)
The GoogleApiWrapper
is a Higher Order Component(HOC) that provides wrapper around Google APIs. Alternatively, the GoogleApiWrapper HOC can be configured by passing a function that will be called with the wrapped component’s props and should return the configuration object like so.
GoogleApiWrapper
是一个高阶组件(HOC) ,可提供围绕Google API的包装。 或者,可以通过传递一个函数来配置GoogleApiWrapper HOC,该函数将使用包装的组件的props进行调用,并且应该像这样返回配置对象。
export default GoogleApiWrapper(
(props) => ({
apiKey: props.apiKey
}
))(MapContainer)
设置标记和infoWindow
(Setting Up Markers and infoWindow
)
We’ll now add a Marker and an infoWindow to our code.
现在,我们将标记和一个infoWindow添加到我们的代码中。
First we need to import Marker
and infoWindow
components from the google-maps-react
library inorder to help us achieve loading of the two.
首先,我们需要从google-maps-react
库中导入Marker
和infoWindow
组件,以帮助我们实现两者的加载。
import { GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
Notice that our component before was stateless? We need to add state for state management.
注意到我们之前的组件是无状态的吗? 我们需要为状态管理添加状态。
[...]
export class MapContainer extends Component {
state = {
showingInfoWindow: false, //Hides or the shows the infoWindow
activeMarker: {}, //Shows the active marker upon click
selectedPlace: {} //Shows the infoWindow to the selected place upon a marker
};
Next, we need to add event handlers for when the map and the marker are clicked.
接下来,我们需要为单击地图和标记的时间添加事件处理程序。
onMarkerClick = (props, marker, e) =>
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
onClose = props => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
};
The
onMarkerClick
method is used to show theInfoWindow
which is a component in the google-maps-react library which gives us the ability for a pop-up window showing details of the clicked place/marker.onMarkerClick
方法用于显示InfoWindow
,它是google-maps-react库中的一个组件,它使我们能够使用弹出窗口来显示单击的位置/标记的详细信息。
Sidenote: the visibility of the infoWindow is controlled by the boolean visible prop which shows the InfoWindow component when true and hides it when false.
旁注:infoWindow的可见性由布尔可见道具控制,该道具在true时显示InfoWindow组件,在false时隐藏它。
The
onClose
method is for closing theInfoWindow
once a user clicks on the close button on theinfoWindow
.onClose
方法用于在用户单击infoWindow
上的关闭按钮后关闭InfoWindow
。
Let’s complete our component by adding our Marker and InfoWindow components to our render method
让我们通过将Marker和InfoWindow组件添加到render方法中来完善我们的组件
render() {
return (
<Map
google={this.props.google}
zoom={14}
style={style}
initialCenter={{ lat: -1.2884, lng: 36.8233 }
>
<Marker
onClick={this.onMarkerClick}
name={'Kenyatta International Convention Centre'}
/>
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
</div>
</InfoWindow>
</Map>
);
}
}
[...]
Run your app and ensure you have the one marker with the infoWindow upon click.
运行您的应用程序,并确保单击时有一个带有InfoWindow的标记。
As a follow-up practice, you can go and add a few more markers on your map and more interactivity to your infoWindow
.
作为后续练习,您可以在地图上添加更多标记,并增加与infoWindow
交互infoWindow
。
浏览器的当前位置 (Browser’s current location)
We’ll now set up our map to pick our browser’s current location. We’ll be using navigator which is a read-only property that returns a Geolocation object that gives Web content access to the location of the device.
现在,我们将设置地图以选择浏览器的当前位置。 我们将使用导航器 ,它是一个只读属性,它返回Geolocation对象,该对象使Web内容可以访问设备的位置。
In our src
folder create a new file and name it Map.js
and create a component named CurrentLocation
this is where all our functionality to pick our browser’s location will lie.
在我们的src
文件夹中,创建一个新文件,并将其命名为Map.js
并创建一个名为CurrentLocation
的组件,这是我们选择浏览器位置的所有功能所在。
We’ll begin by adding some default props to our CurrentLocation
component, since we’ll need to set the map with a center incase the current location is not provided.This is handled by the boolean prop centerAroundCurrentLocation
我们先在CurrentLocation
组件中添加一些默认道具,因为在未提供当前位置的情况下,我们需要使用中心设置地图,这由布尔道具centerAroundCurrentLocation
处理
import React from 'react';
import ReactDOM from 'react-dom';
const mapStyles = {
map: {
position: 'absolute',
width: '100%',
height: '100%'
}
};
export class CurrentLocation extends React.Component {
[...]
}
export default CurrentLocation;
CurrentLocation.defaultProps = {
zoom: 14,
initialCenter: {
lat: -1.2884,
lng: 36.8233
},
centerAroundCurrentLocation: false,
visible: true
};
Next, we need to make our component stateful,
接下来,我们需要使组件处于有状态,
[...]
export class CurrentLocation extends React.Component {
constructor(props) {
super(props);
const { lat, lng } = this.props.initialCenter;
this.state = {
currentLocation: {
lat: lat,
lng: lng
}
};
}
[...]
}
Let’s also update our CurrentLocation component to cater for the instance when the Map is first loaded as we cannot solely depend upon the google API being always available, hence we need to check if it’s loaded. And also check if the browser’s current location is provided and recenter the map to it.
让我们还更新我们的CurrentLocation组件,以适应首次加载地图时的实例,因为我们不能仅仅依赖于始终可用的google API,因此我们需要检查它是否已加载。 还要检查是否提供了浏览器的当前位置,并将地图更新到该位置。
[...]
componentDidUpdate(prevProps, prevState) {
if (prevProps.google !== this.props.google) {
this.loadMap();
}
if (prevState.currentLocation !== this.state.currentLocation) {
this.recenterMap();
}
}
[...]
Let’s define the recenterMap()
function which only gets called when the currentLocation in the component’s state is updated and uses the .panTo()
method on the google.maps.Map instance to change the center of the map.
让我们定义一个recenterMap()
函数,该函数仅在组件状态下的currentLocation更新时才调用,并使用google.maps.Map实例上的.panTo()
方法更改地图的中心。
[...]
recenterMap() {
const map = this.map;
const current = this.state.currentLocation;
const google = this.props.google;
const maps = google.maps;
if (map) {
let center = new maps.LatLng(current.lat, current.lng);
map.panTo(center);
}
}
[...]
Next, we need to handle the instance when the map has already loaded.This will be handled by the componentDidMount()
Lifecycle method which will set a call back to fetch the current location.
接下来,我们需要在地图加载后处理实例,这将由componentDidMount()
Lifecycle方法处理,该方法将设置回叫以获取当前位置。
[...]
componentDidMount() {
if (this.props.centerAroundCurrentLocation) {
if (navigator && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(pos => {
const coords = pos.coords;
this.setState({
currentLocation: {
lat: coords.latitude,
lng: coords.longitude
}
});
});
}
}
this.loadMap();
}
[...]
Notice the loadMap()
function? Let’s go on ahead and define it.
注意loadMap()
函数吗? 让我们继续定义它。
[...]
loadMap() {
if (this.props && this.props.google) {
// checks if google is available
const { google } = this.props;
const maps = google.maps;
const mapRef = this.refs.map;
// reference to the actual DOM element
const node = ReactDOM.findDOMNode(mapRef);
let { zoom } = this.props;
const { lat, lng } = this.state.currentLocation;
const center = new maps.LatLng(lat, lng);
const mapConfig = Object.assign(
{},
{
center: center,
zoom: zoom
}
);
// maps.Map() is constructor that instantiates the map
this.map = new maps.Map(node, mapConfig);
}
}
The loadMap()
function is only called after the component has been rendered and grabs a reference to the DOM component to where we want our map to be placed.
仅在呈现组件之后,才调用loadMap()
函数,并获取对DOM组件的引用,该引用指向我们要放置地图的位置。
Our CurrentLocation component is almost looking up, But we need to ensure that our previous Marker picks our current location ie the browsers current location and so we need to introduce Parent-Child concept through the renderChildren()
method which will be responsible for calling the method on the child component.
我们的CurrentLocation组件几乎要查找,但是我们需要确保先前的标记选择了我们的当前位置,即浏览器的当前位置,因此我们需要通过renderChildren()
方法引入Parent-Child概念,该方法将负责调用该方法在子组件上。
Read more about Parent-Child communication here
[...]
renderChildren() {
const { children } = this.props;
if (!children) return;
return React.Children.map(children, c => {
if (!c) return;
return React.cloneElement(c, {
map: this.map,
google: this.props.google,
mapCenter: this.state.currentLocation
});
});
}
[...]
And finally, let’s add our render()
method
最后,让我们添加render()
方法
[...]
render() {
const style = Object.assign({}, mapStyles.map);
return (
<div>
<div style={style} ref="map">
Loading map...
</div>
{this.renderChildren()}
</div>
);
}
[...]
Lastly, before we wind up we need to update our MapContainer
component to include our new changes. So let’s change it to this
最后,在结束之前,我们需要更新MapContainer
组件以包括我们的新更改。 所以我们将其更改为
import React, { Component } from 'react';
import { GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
import CurrentLocation from './Map';
export class MapContainer extends Component {
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {}
};
onMarkerClick = (props, marker, e) =>
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
onClose = props => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
};
render() {
return (
<CurrentLocation
centerAroundCurrentLocation
google={this.props.google}
>
<Marker onClick={this.onMarkerClick} name={'current location'} />
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
</div>
</InfoWindow>
</CurrentLocation>
);
}
}
export default GoogleApiWrapper({
apiKey: 'YOUR_GOOGLE_API_KEY_GOES_HERE'
})(MapContainer);
Run your app; heading over to our browser, our map should first load with our initialCenter
then reload to pick our browser’s current location with the marker positioned to this location and Voilà we are done.
运行您的应用; 转到浏览器,我们的地图应该首先加载我们的initialCenter
然后重新加载以选择浏览器的当前位置,并将标记定位到该位置,然后完成操作。
结论 (Conclusion)
In this article we’ve been able to load our Maps React component, add a marker and have an infoWindow
onto it. We also made the map pick our current location. From here, you can implement more advanced features such as having polylines and polygons or adding event listeners into your maps.
在本文中,我们已经能够加载Maps React组件,添加标记并在其上添加一个infoWindow
。 我们还使地图选择了我们的当前位置。 从这里,您可以实现更高级的功能,例如具有折线和多边形或将事件侦听器添加到地图中。
react集成钉钉api