Thứ sáu, 11/09/2020 | 00:00 GMT+7

Cách tích hợp API Google Maps vào các ứng dụng React

Google Maps là một dịch vụ bản đồ do Google cung cấp, hỗ trợ nhiều loại cài đặt cấu hình. Việc thêm Google Maps vào ứng dụng của bạn có thể cung cấp cho user nhiều thông tin theo ngữ cảnh hơn là địa chỉ đường phố hoặc tập hợp các tọa độ.

Hướng dẫn này nhằm mục đích tích hợp API Google Maps vào các thành phần React của bạn và cho phép bạn hiển thị bản đồ trên trang web của bạn .

Yêu cầu

Để hoàn thành hướng dẫn này, bạn cần :

Lưu ý: Để tránh thông báo "Chỉ dành cho mục đích phát triển" khi sử dụng API Google Maps, bạn cần cung cấp thẻ tín dụng hợp lệ và liên kết với account Thanh toán cho Dự án Google Cloud, nhưng không bắt buộc đối với hướng dẫn này.

Hướng dẫn này đã được xác minh với Node v14.2.0, npm v6.14.5, react v16.13.1, và google-maps-react v.2.0.6.

Bước 1 - Cài đặt ứng dụng React

Đối với hướng dẫn này, bạn sẽ sử dụng create-react-app dụng create-react-app để xây dựng một ứng dụng React mới.

Đầu tiên, chạy npx để sử dụng create-react-app npx create-react-app trong cửa sổ dòng lệnh:

  • npx create-react-app react-googlemaps

Sau đó, chuyển đến folder dự án mới của bạn:

cd react-googlemaps 

Trước khi bạn thêm bất kỳ mã nào, hãy cài đặt các phụ thuộc của bạn với:

  • npm install google-maps-react@2.0.6

Lưu ý: Theo tùy chọn, tại thời điểm này, bạn có thể xóa các file và nhập không cần thiết trong folder src của bạn . Bạn sẽ không yêu cầu logo.svg , App.css , index.css . Nếu bạn xóa index.css , bạn cũng nên xóa import cho index.css trong index.html để tránh lỗi bản dựng.

Đến đây, bạn có một ứng dụng React với thư viện google-maps-react . Đến đây bạn có thể khám phá bằng cách sử dụng bản đồ trong ứng dụng của bạn .

Bước 2 - Sử dụng MapGoogleApiWrapper

Tiếp theo, bạn cần chỉnh sửa file App.js của bạn và thay thế mã bằng thành phần sẽ tải Google Map của bạn.

Mở App.js :

  • nano src/App.js

Thay thế nội dung của App.js bằng các dòng mã sau:

src / App.js
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_MAPS_API_KEY_GOES_HERE' })(MapContainer); 

Lưu ý: Thay thế YOUR_GOOGLE_MAPS_API_KEY_GOES_HERE bằng Khóa API JavasScript của Google Maps của bạn.

Cảnh báo: Đảm bảo tránh lưu khóa API của bạn trong các file nào bạn commit vào các repository công khai (như GitHub) vì sau đó nó có thể được người khác sử dụng cho các mục đích mà bạn không có ý định.

Đối với chức năng của Bản đồ Google cơ bản, đây là tất cả mã bạn cần.

Thành phần Map có một số đạo cụ tùy chọn:

  • style - đối tượng kiểu CSS
  • zoom - giá trị số thể hiện tiêu điểm chặt chẽ hơn ở trung tâm bản đồ
  • initialCenter - một đối tượng có chứa vĩ độ và kinh độ

Trong ví dụ này, bạn đang xác định:

  • một đối tượng kiểu CSS có 100% chiều rộng và 100% chiều cao
  • giá trị thu phóng là 14
  • và vị trí -1.2884, 36.8233 (Trung tâm Hội nghị Quốc tế Kenyatta ở Nairobi, Kenya)

Mở terminal của bạn và chạy ứng dụng của bạn:

  • npm start

Và đảm bảo bản đồ tải vào trình duyệt:

Bản đồ hiển thị trong trình duyệt

GoogleApiWrapperThành phần có thứ tự cao hơn (HOC) cung cấp một shell bọc xung quanh các API của Google. Ngoài ra, GoogleApiWrapper HOC có thể được cấu hình bằng cách chuyển một hàm sẽ được gọi với các đạo cụ của thành phần được bao bọc và sẽ trả về đối tượng cấu hình như sau:

export default GoogleApiWrapper(   (props) => ({     apiKey: props.apiKey   } ))(MapContainer) 

Đến đây, bạn có Bản đồ Google trong ứng dụng React của bạn . Như vậy, bạn có thể khám phá việc triển khai các tính năng khác của Google Maps.

Bước 3 - Sử dụng MarkersInfoWindow

Đến đây bạn sẽ thêm MarkerInfoWindow vào mã của bạn.

Trước tiên, bạn cần nhập các thành phần MarkerInfoWindow từ thư viện google-maps-react InfoWindow để giúp bạn tải cả hai.

src / App.js
import React, { Component } from 'react'; import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react'; 

Lưu ý thành phần của bạn trước đây là không trạng thái? Bạn cần thêm trạng thái để quản lý nhà nước.

src / App.js
// ...  export class MapContainer extends Component {   state = {     showingInfoWindow: false,  // Hides or shows the InfoWindow     activeMarker: {},          // Shows the active marker upon click     selectedPlace: {}          // Shows the InfoWindow to the selected place upon a marker   };    // ... } 

Tiếp theo, bạn cần thêm trình xử lý sự kiện khi MapMarker được nhấp vào.

src / App.js
// ...  export class MapContainer extends Component {   // ...    onMarkerClick = (props, marker, e) =>     this.setState({       selectedPlace: props,       activeMarker: marker,       showingInfoWindow: true     });    onClose = props => {     if (this.state.showingInfoWindow) {       this.setState({         showingInfoWindow: false,         activeMarker: null       });     }   };    // ... } 

Phương thức onMarkerClick được sử dụng để hiển thị InfoWindow , là một thành phần trong thư viện google-maps-react InfoWindow , cung cấp cho bạn khả năng cửa sổ bật lên hiển thị chi tiết của Marker nhấp.

Phương thức onClose dùng để đóng InfoWindow sau khi user nhấp vào nút đóng trên InfoWindow .

Hãy hoàn thành phần của bạn bằng cách thêm <Marker><InfoWindow> thành phần đến render phương pháp:

src / App.js
// ...  export class MapContainer extends Component {   // ...    render() {     return (       <Map         google={this.props.google}         zoom={14}         style={mapStyles}         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>     );   } } 

Chạy ứng dụng của bạn:

  • npm start

Và đảm bảo bạn có một Marker với InfoWindow khi nhấp chuột:

Bản đồ với Marker và InfoWindow hiển thị trong trình duyệt

Như một phương pháp tiếp theo, bạn có thể thêm một vài <Marker> trên <Map> và nhiều tương tác hơn vào <InfoWindow> của bạn.

Bước 4 - Hiển thị Vị trí Hiện tại của User

Đến đây bạn sẽ cài đặt bản đồ của bạn để truy xuất vị trí hiện tại của trình duyệt. Bạn sẽ sử dụng Bộ chuyển , là thuộc tính chỉ đọc trả về một đối tượng Vị Geolocation cho phép nội dung web truy cập vào vị trí của thiết bị.

Trong folder src của bạn, tạo một file mới và đặt tên là Map.js :

  • nano src/Map.js

Bạn sẽ tạo một thành phần có tên là CurrentLocation - đây là nơi bạn sẽ xây dựng tất cả các chức năng để truy xuất vị trí của trình duyệt của bạn:

src / Map.js
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; 

Bạn sẽ bắt đầu bằng cách thêm một số đạo cụ mặc định vào thành phần <CurrentLocation> , vì bạn cần đặt bản đồ với center trong trường hợp vị trí hiện tại không được cung cấp. Điều này được xử lý bởi boolean prop centerAroundCurrentLocation :

src / Map.js
// ...  CurrentLocation.defaultProps = {   zoom: 14,   initialCenter: {     lat: -1.2884,     lng: 36.8233   },   centerAroundCurrentLocation: false,   visible: true }; 

Tiếp theo, bạn cần làm cho thành phần của bạn ở trạng thái:

src / Map.js
// ...  export class CurrentLocation extends React.Component {   constructor(props) {     super(props);      const { lat, lng } = this.props.initialCenter;      this.state = {       currentLocation: {         lat: lat,         lng: lng       }     };   } }  // ... 

Cũng hãy cập nhật thành phần <CurrentLocation> của bạn để xử lý các trường hợp khi API Google Maps không khả dụng do sự cố mạng hoặc bảo trì đột xuất. Và cũng xử lý các tình huống khi vị trí hiện tại của trình duyệt được cung cấp và gần đây hơn bản đồ đến vị trí đó.

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    componentDidUpdate(prevProps, prevState) {     if (prevProps.google !== this.props.google) {       this.loadMap();     }     if (prevState.currentLocation !== this.state.currentLocation) {       this.recenterMap();     }   } }  // ... 

Hãy xác định hàm recenterMap() được gọi khi vị trí currentLocation trong trạng thái của thành phần được cập nhật. Nó sẽ sử dụng phương thức panTo() để thay đổi tâm của bản đồ.

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    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);     }   } }  // ... 

Tiếp theo, bạn cần xử lý tình huống khi bản đồ đã được tải. Điều này sẽ được xử lý bởi phương thức vòng đời componentDidMount() phương thức này sẽ cài đặt một lệnh gọi lại để tìm nạp vị trí hiện tại.

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    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();<^>   } }  // ... 

Chú ý đến loadMap() ? Hãy tiếp tục và xác định nó.

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    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);     }   } }  // ... 

Hàm loadMap() được gọi sau khi thành phần đã được kết xuất và lấy một tham chiếu đến thành phần DOM đến nơi bạn muốn đặt bản đồ của bạn .

Thành phần <CurrentLocation> của bạn gần như hoàn tất. Nhưng bạn cần đảm bảo <Marker> trước đó của bạn chọn vị trí hiện tại của bạn (tức là vị trí hiện tại của trình duyệt) và vì vậy bạn cần giới thiệu giao tiếp thành phần Parent-Child thông qua phương thức renderChildren() sẽ chịu trách nhiệm gọi phương thức trên thành phần con.

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    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       });     });   } }  // ... 

Và cuối cùng, hãy thêm phương thức render() của bạn:

src / Map.js
// ...  export class CurrentLocation extends React.Component {   // ...    render() {     const style = Object.assign({}, mapStyles.map);      return (       <div>         <div style={style} ref="map">           Loading map...         </div>         {this.renderChildren()}       </div>     );   } }  // ... 

Cuối cùng, bạn cần cập nhật thành phần MapContainer của bạn trong App.js :

  • nano src/App.js

Thay thế thành phần Map bằng thành phần CurrentLocation mới của bạn:

src / App.js
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_MAPS_API_KEY_GOES_HERE' })(MapContainer); 

Chạy ứng dụng của bạn:

npm start 

Tiêu đề trên trình duyệt của bạn, bản đồ của bạn đầu tiên nên tải với bạn initialCenter sau đó reload để chọn vị trí hiện tại của trình duyệt của bạn với các Marker vị trí đến vị trí này và thì đấy, bạn đang thực hiện:

Bản đồ với Vị trí hiện tại hiển thị trong trình duyệt

Kết luận

Trong bài viết này, bạn có thể tải thành phần React <Map> , thêm Marker và liên kết InfoWindow với nó. Bạn cũng đã làm cho bản đồ hiển thị vị trí hiện tại của bạn.

Dựa trên kiến thức này, bạn có thể triển khai các tính năng nâng cao hơn như có đa giác và đa giác hoặc thêm trình xử lý sự kiện vào bản đồ của bạn .

Nếu bạn muốn tìm hiểu thêm về React, hãy xem loạt bài Cách viết mã trong React.js của ta hoặc xem trang chủ đề React của ta để biết các bài tập và dự án lập trình.


Tags:

Các tin liên quan