#reactjs #google-maps
#reactjs #google-карты
Вопрос:
Я хочу создать приложение, чтобы пользователь мог установить пункт назначения с помощью автозаполнения, а затем показать маршрут с помощью средства визуализации направлений. Сейчас я исправляю исходное местоположение и пытаюсь изменить только пункт назначения. это компонент карты в моем приложении. это код, который я нашел, чтобы указать направления, если есть какой-либо другой способ, пожалуйста, покажите мне. Я новичок в react. и еще один вопрос, консоль показывает это предупреждение при запуске приложения:
index.js:1 Warning: Legacy context API has been detected within a strict-mode tree.
Старый API будет поддерживаться во всех версиях 16.x, но приложения, использующие его, должны перейти на новую версию.
Пожалуйста, обновите следующие компоненты: withGoogleMap(lifecycle(portal))
Что я должен делать?
import React, { useState } from 'react';
import { compose, withProps, lifecycle } from "recompose";
import Autocomplete from 'react-google-autocomplete';
import { withScriptjs, withGoogleMap, GoogleMap, Marker, DirectionsRenderer, Polygon } from "react-google-maps";
import PersistentDrawerLeft from './drawer';
import { Place, Search } from '@material-ui/icons';
import { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
import { render } from '@testing-library/react';
const GoogleMapContainer =
compose(
withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=your-api-key.expamp;libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `100%` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withScriptjs,
withGoogleMap,
lifecycle({
componentDidMount() {
const DirectionsService = new window.google.maps.DirectionsService();
DirectionsService.route({
origin: new window.google.maps.LatLng(40.8525800, -87.6514100),
destination: new window.google.maps.LatLng(40.0525800, -87.6514100),
travelMode: window.google.maps.TravelMode.DRIVING,
}, (result, status) => {
if (status === window.google.maps.DirectionsStatus.OK) {
this.setState({
directions: result,
});
} else {
console.error(`error fetching directions ${result}`);
}
});
}
})
)(function portal(props) {
let lat = null;
let lng = null;
const [placeselected, SetPlaceselected] = useState(null);
return(
<GoogleMap
defaultZoom={8}
defaultCenter={{ lat: 40.8525800, lng: -87.6514100 }}
>
<Autocomplete
key = {'from'}
onPlaceSelected={(place) => {
lat = place.geometry.location.lat();
lng = place.geometry.location.lng();
console.log(lat, lng);
const DirectionsService = new window.google.maps.DirectionsService();
DirectionsService.route({
origin: new window.google.maps.LatLng(40.8525800, -87.6514100),
destination: new window.google.maps.LatLng(lat, lng),
travelMode: window.google.maps.TravelMode.DRIVING,
}, (result, status) => {
if (status === window.google.maps.DirectionsStatus.OK) {
console.log('it worked');
SetPlaceselected(result);
console.log(placeselected);
} else {
console.error(`error fetching directions ${result}`);
}
});
}}
style={{
width: '100%',
height: '40px',
paddingLeft: '16px',
marginTop: '2px',
marginBottom: '2rem'
}}
types={['(regions)']}
/>
{placeselected amp;amp; (console.log(placeselected), <DirectionsRenderer directions={placeselected} />)}
{props.directions amp;amp; <DirectionsRenderer directions={props.directions} />}
</GoogleMap>
)})
export default GoogleMapContainer;
Ответ №1:
Я не могу воспроизвести ошибку, которую вы получаете. Я успешно воспроизвел ваш вариант использования 2 способами: один с использованием обоих react-google-maps
и react-google-autocomplete
и один без использования каких-либо библиотек. Я также поместил скрипт Google Maps в отдельный JS-файл, чтобы в определенном JS-файле (компоненте) можно было видеть только функциональность карты.
Вот пример кода с использованием библиотек. Фрагмент кода:
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import { withScriptjs } from "react-google-maps";
import Map from './Map';
import './style.css';
const App = () => {
const MapLoader = withScriptjs(Map);
return (
<MapLoader
googleMapURL="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYamp;libraries=places,geometry"
loadingElement={<div style={{ height: `100%` }} />}
/>
);
};
render(<App />, document.getElementById('root'));
Map.js
/*global google*/
import React, { Component } from "react";
import {
withGoogleMap,
withScriptjs,
GoogleMap,
DirectionsRenderer,
} from "react-google-maps";
import Autocomplete from "react-google-autocomplete";
class Map extends Component {
state = {
directions: null,
};
componentDidMount() {
const directionsService = new google.maps.DirectionsService();
const origin = { lat: 40.85258, lng: -87.65141 };
const destination = { lat: 40.05258, lng: -87.65141 };
directionsService.route(
{
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
this.setState({
directions: result,
});
} else {
console.error(`error fetching directions ${result}`);
}
}
);
}
onPlaceSelected = (place) => {
const directionsService = new google.maps.DirectionsService();
const origin = { lat: 40.85258, lng: -87.65141};
const destination = place.geometry.location;
directionsService.route(
{
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
this.setState({
directions: result,
});
} else {
console.error(`error fetching directions ${result}`);
}
}
);
};
render() {
const Auto = (props) => (
<Autocomplete
style={{ width: "90%" }}
onPlaceSelected={(place) => {
console.log(place);
this.onPlaceSelected(place);
}}
types={["(regions)"]}
/>
);
const GoogleMapExample = withGoogleMap((props) => (
<GoogleMap
defaultCenter={{ lat: 40.756795, lng: -73.954298 }}
defaultZoom={13}
>
{this.state.directions amp;amp; (
<DirectionsRenderer directions={this.state.directions} />
)}
</GoogleMap>
));
return (
<div>
<div style={{ margin: `15px` }}>
<h3>Choose another destination</h3>
<Auto />
</div>
<GoogleMapExample
containerElement={<div style={{ height: `500px`, width: "500px" }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
}
export default Map;
Вот пример кода без использования каких-либо библиотек react.
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import App from './App';
import './style.css';
render(<App />, document.getElementById('root'));
Map.js
import React, { Component } from "react";
import { render } from "react-dom";
class Map extends Component {
constructor() {
this.onScriptLoad = this.onScriptLoad.bind(this);
}
onScriptLoad() {
const map = new window.google.maps.Map(
document.getElementById(this.props.id),
this.props.options
);
this.props.onMapLoad(map);
}
componentDidMount() {
if (!window.google) {
let s = document.createElement("script");
s.type = "text/javascript";
s.src = `https://maps.google.com/maps/api/js?key=YOUR_API_KEYamp;libraries=places`;
let x = document.getElementsByTagName("script")[0];
x.parentNode.insertBefore(s, x);
// Below is important.
//We cannot access google.maps until it's finished loading
s.addEventListener("load", (e) => {
this.onScriptLoad();
});
} else {
this.onScriptLoad();
}
}
render() {
return (
<div>
<div className="pac-card" id="pac-card">
<div>
<div id="title">Search Destination</div>
<div id="pac-container">
<input
id="pac-input"
type="text"
placeholder="Enter a location"
/>
</div>
</div>
</div>
<div style={{ width: 500, height: 500 }} id={this.props.id} />
<div id="infowindow-content">
<img src="" width="16" height="16" id="place-icon" />
<span id="place-name" className="title"></span>
<br />
<span id="place-address"></span>
<br />
<span id="place-coord"></span>
</div>
</div>
);
}
}
export default Map;
App.js
import React, { Component } from "react";
import { render } from "react-dom";
import Map from "./Map";
import "./style.css";
class App extends Component {
render() {
return (
<Map
id="myMap"
options={{
center: { lat: 40.85258, lng: -87.65141 },
zoom: 6,
}}
onMapLoad={(map) => {
let card = document.getElementById("pac-card");
let input = document.getElementById("pac-input");
//Set Direction for primary origin and destination
let directionsService = new google.maps.DirectionsService();
let directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
let start = { lat: 40.85258, lng: -87.65141 };
let end = { lat: 40.05258, lng: -87.65141 };
let request = {
origin: start,
destination: end,
travelMode: "DRIVING",
};
directionsService.route(request, function (result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
}
});
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
let autocomplete = new google.maps.places.Autocomplete(input);
// Bind the map's bounds (viewport) property to the autocomplete object,
// so that the autocomplete requests use the current map bounds for the
// bounds option in the request.
autocomplete.bindTo("bounds", map);
// Set the data fields to return when the user selects a place.
autocomplete.setFields([
"address_components",
"geometry",
"icon",
"name",
]);
//listener for the places input
autocomplete.addListener("place_changed", function () {
let place = autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
window.alert(
"No details available for input: '" place.name "'"
);
return;
}
//setting request again with the new destination
request = {
origin: start,
destination: place.geometry.location,
travelMode: "DRIVING",
};
directionsService.route(request, function (result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
}
});
});
}}
/>
);
}
}
export default App;