I'm trying to use the react-google-maps package to show a map with a draggable marker, that has an infowindow that displays the address of the location of the marker.
As of now it works and can retrieve the address and display it, however I have run into the problem of the whole map re-rendering, when really only the marker infowindow needs to re-render.
This is probably due to the fact that I'm changing the state of the map component when I set the originaddress and coordinates in handleOriginMarkerChange(), which are stored in the map component state. I'm new to react, and am not sure of the proper way to solve this, so any pointing in the right direction would be helpful!
Below is the code for my Map.js
import React, { Component } from 'react';
import {InfoWindow, withGoogleMap, GoogleMap ,Marker,MarkerWithLabel} from 'react-google-maps';
class Map extends Component {
constructor (props) {
super(props)
this.state = {
destination:"default",
showSecondMarker:false,
originLat:0.0,
originLng:0.0,
destinationLat:0.0,
destinationLng:0.0,
originAddress:"",
destinationAddress:"",
};
this.handleOriginMarkerChange = this.handleOriginMarkerChange.bind(this);
}
handleOriginMarkerChange(e){
Geocoder.getFromLatLng(e.latLng.lat(), e.latLng.lng()).then(
json => {
var address_component = json.results[0].formatted_address;
address_component= address_component.substring(0, address_component.indexOf(','));
this.setState({originAddress:address_component,originLat:e.latLng.lat(),originLng:e.latLng.lng()});
},
error => {
alert(error);
}
);
}
render() {
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
center={center}
zoom={this.getZoomLevel()}
onClick={props.onMapClick}
defaultOptions={{ styles: mapStyle,
fullscreenControl:true,
rotateControl: false,
mapTypeControl: false,
streetViewControl: false }}
>
{props.showSecondMarker && <Marker options={{icon: '/icon_to.png'}} draggable={!this.state.isDestinationSelected} onClick={this.destinationMarkerClicked} onDragEnd={this.handleDestinationMarkerChange} position={{ lat:this.state.destinationLat , lng: this.state.destinationLng }} >
{this.state.showDestinationInfoWindow &&<InfoWindow>
<div className="info-window-style">
<h4>{this.state.destinationAddress}</h4>
{destinationInfoButton}
</div>
</InfoWindow>}
</Marker>}}
{<Marker draggable={!this.state.isOriginSelected} options={{icon: '/icon_from.png'}} onDragEnd={this.handleOriginMarkerChange} onClick={this.originMarkerClicked} position={{ lat:this.state.originLat, lng:this.state.originLng }}>
{this.state.showOriginInfoWindow &&<InfoWindow>
<div className="info-window-style">
<h4>{this.state.originAddress}</h4>
{originInfoButton}
</div>
</InfoWindow>}
</Marker>}
</GoogleMap>
));
return(
<div style={{ height: 350,
width: '100%',
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'center',
padding: 0 }}>
<GoogleMapExample
showSecondMarker={this.state.showSecondMarker}
onMapClick={this.handleMapClick}
containerElement={ <div style={{ width: "100%", marginLeft: 0,marginRight:10}}/> }
mapElement={ <div style={{ height: `200%` }} /> }
/>
</div>
);
}
};
export default Map;