Reputation: 169
I am new to React and am attempting to use google maps to display directions. I have been able to get it to display a single marker but have not found how to reconfigure the code to display the directions. Below is my most recent attempt but it will only display the map... any assistance is appreciated:
import React, { Component } from 'react';
import { withGoogleMap, GoogleMap, DirectionsRenderer } from 'react-google-maps';
class Map extends Component {
render() {
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
defaultCenter = { { lat: 40.756795, lng: -73.954298 } }
defaultZoom = { 13 }
>
<DirectionsRenderer origin={{ lat: 40.756795, lng: -73.954298 }} destination={{ lat: 41.756795, lng: -78.954298 }} />
</GoogleMap>
));
return(
<div>
<GoogleMapExample
containerElement={ <div style={{ height: `500px`, width: '500px' }} /> }
mapElement={ <div style={{ height: `100%` }} /> }
/>
</div>
);
}
};
export default Map;
I have the API key in a script tag in index.html
Upvotes: 6
Views: 31027
Reputation: 252
Similar to @VadimGremyachev and @EmmanuelAdebayo's answers (many thanks!), but with an arrow function and a useState hook:
import React, { useState } from "react";
import { GoogleMap, Marker, DirectionsRenderer } from "react-google-maps";
/* global google */
const Map = ({ formattedOrigin, formattedDestination }) => {
const DirectionsService = new google.maps.DirectionsService();
let [directions, setDirections] = useState("");
DirectionsService.route(
{
origin: formattedOrigin,
destination: formattedDestination,
travelMode: google.maps.TravelMode.DRIVING,
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
setDirections(result);
} else {
console.error(`error fetching directions ${result}`);
}
}
);
return (
<section className="googleMap">
<GoogleMap defaultZoom={9} defaultCenter={{ lat: 41.75, lng: 1.8 }}>
<Marker position={formattedOrigin} />
<Marker position={formattedDestination} />
{directions && <DirectionsRenderer directions={directions} />}
</GoogleMap>
</section>
);
};
export default Map;
And then from your high order component:
import React from "react";
import "../styles/Home.css";
import { useSelector } from "react-redux";
import { googleMapsApiKey } from "../../data/constants";
import { withScriptjs, withGoogleMap } from "react-google-maps";
import Map from "../presentational/Map";
const Home = () => {
const WrappedMap = withScriptjs(withGoogleMap(Map));
const formattedOrigin = useSelector(
(state) => state.routeCalculatorReducer.loadCost?.originGeoCodedFormatted
);
const formattedDestination = useSelector(
(state) =>
state.routeCalculatorReducer.loadCost?.destinationGeoCodedFormatted
);
return (
<main className="home">
<section className="map">
<WrappedMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?libraries=geometry,drawing,places&key=${googleMapsApiKey}`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: "80vh" }} />}
mapElement={<div style={{ height: `100%` }} />}
formattedOrigin={formattedOrigin}
formattedDestination={formattedDestination}
/>
</section>
</main>
);
};
export default Home;
Upvotes: 2
Reputation: 255
This should be the enough example for you to work with
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { withScriptjs } from "react-google-maps";
import Map from './components/Map';
function App() {
const MapLoader = withScriptjs(Map);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
</header>
<MapLoader
googleMapURL="https://maps.googleapis.com/maps/api/js?key=Key"
loadingElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
export default App;
And your Map.js file should look like this
/*global google*/
import React, { Component } from "react";
import {
withGoogleMap,
withScriptjs,
GoogleMap,
DirectionsRenderer
} from "react-google-maps";
class Map extends Component {
state = {
directions: null,
};
componentDidMount() {
const directionsService = new google.maps.DirectionsService();
const origin = { lat: 6.5244, lng: 3.3792 };
const destination = { lat: 6.4667, lng: 3.4500};
directionsService.route(
{
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
waypoints: [
{
location: new google.maps.LatLng(6.4698, 3.5852)
},
{
location: new google.maps.LatLng(6.6018,3.3515)
}
]
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
console.log(result)
this.setState({
directions: result
});
} else {
console.error(`error fetching directions ${result}`);
}
}
);
}
render() {
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
defaultCenter={{ lat: 6.5244, lng: 3.3792 }}
defaultZoom={13}
>
<DirectionsRenderer
directions={this.state.directions}
/>
</GoogleMap>
));
return (
<div>
<GoogleMapExample
containerElement={<div style={{ height: `500px`, width: "500px" }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
}
export default Map;
I hope this helps you
Upvotes: 3
Reputation: 59378
DirectionsRenderer
component does not accept origin
and destination
props, directions
prop needs to be provided instead which value represents the response from DirectionsService
, for example:
<DirectionsRenderer
directions={this.state.directions}
/>
where
const directionsService = new google.maps.DirectionsService();
const origin = { lat: 40.756795, lng: -73.954298 };
const destination = { lat: 41.756795, lng: -78.954298 };
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}`);
}
}
);
Upvotes: 13