very new to react. I'm using google-maps-react-api. I have two files. Index.js and MapMarker.js. It loads a few location points with info windows already loaded. I can close the window but when clicking on the marker they do not reopen. My onCLick events do not work as I expect. I want the case to be the markers load and I click them to show info window and then can close the window as well. I've read the docs and issues on Github but can't find the info. Thanks.
Index.js
import ReactDOM from "react-dom";
import React from "react";
import { GoogleMap, LoadScript, MarkerClusterer } from "@react-google-maps/api";
import MapMarker from "./MapMarker";
const mapOptions = {
fullscreenControl: false,
streetViewControl: false,
mapTypeControl: false,
styles: [
{
featureType: "poi",
elementType: "labels",
stylers: [
{
visibility: "off"
}
]
},
{
featureType: "transit",
elementType: "all",
stylers: [
{
visibility: "off"
}
]
}
]
};
const key = ""; // PUT GMAP API KEY HERE
const defaultLocation = {
lat: 37.9755691,
lng: 23.7361789
};
let markers = [
{
id: 1,
lat: 37.975,
lng: 23.7361789
},
{
id: 2,
lat: 37.9755,
lng: 23.7361789
},
{
id: 3,
lat: 37.976,
lng: 23.7361789
}
];
class Map extends React.Component {
state = {
isInfoOpen: false,
selectedMarkerId: null,
noOfClusters: null,
markers: markers
};
onClick = (isInfoOpen, selectedMarkerId) => {
this.setState({
isInfoOpen,
selectedMarkerId
});
};
render() {
const { isInfoOpen, selectedMarkerId } = this.state;
return (
<LoadScript googleMapsApiKey={key} >
<div>
<div
style={{
width: "100%",
height: 500,
display: "flex"
}}
>
<GoogleMap
options={mapOptions}
center={defaultLocation}
zoom={18}
onLoad={this.onMapMounted}
onIdle={this.onMapIdle}
onBoundsChanged={this.onBoundsChanged}
onZoomChanged={this.onZoomChanged}
mapContainerStyle={{ flex: 1 }}
>
<MarkerClusterer averageCenter enableRetinaIcons gridSize={60}>
{clusterer =>
this.state.markers.map(markerData => (
<MapMarker
key={markerData.id}
clusterer={clusterer}
markerData={markerData}
isSelected={markerData.id === selectedMarkerId}
isInfoOpen={
markerData.id === selectedMarkerId && isInfoOpen
}
onClick={() => this.onClick()}
/>
))
}
</MarkerClusterer>
</GoogleMap>
</div>
</div>
</LoadScript>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Map />, rootElement);
MapMarker.js
import React from "react";
import { InfoWindow, Marker} from "@react-google-maps/api";
export default class MapMarker extends React.Component {
state = {
mapMarker: null,
activeMarker: {},
selectedPlace: {},
showingInfoWindow: false
};
onMarkerClick = (props, marker) =>
this.setState({
activeMarker: marker,
selectedPlace: props,
showingInfoWindow: true
});
onInfoWindowClose = () =>
this.setState({
activeMarker: null,
showingInfoWindow: false
});
onLoad = mapMarker => {
this.setState({
mapMarker
});
};
render() {
const { clusterer, markerData } = this.props;
const { mapMarker } = this.state;
return (
<Marker
clusterer={clusterer}
onLoad={this.onLoad}
position={{
lat: markerData.lat,
lng: markerData.lng
}}
onClick={() => this.onMarkerClick()}
>
{mapMarker && (
<InfoWindow
anchor={mapMarker}
position={{
lat: markerData.lat,
lng: markerData.lng
}}
marker={this.state.activeMarker}
onClose={this.onInfoWindowClose}
visible={this.state.showingInfoWindow}
>
<div style={{ background: "white" }}>
{"custom Infobox: " + markerData.id}
</div>
</InfoWindow>
)}
</Marker>
);
}
}
I made a couple of changes in your MapMaker.js from the codesandbox link you provided.
First, I added a state named showingInfoWindow and assign a value of false. This will be the state that will indicate if the infowindow will be shown or not.
Then, I added a function named onMarkerClick which is called everytime the Marker is clicked. This will set the state of showingInfoWindow to true.
Next, I put a condition in the return of MapMaker class, which will only show the infowindow when the showingInfoWindow is set to true.
Then, I add the onInfoWindowClose function that sets the state of showingInfoWindow back to false.
Lastly, I added the onCloseClick parameter in the and call the onInfoWindowClose function.
You can follow the code snippet below for the changes in MapMaker.js
import React from "react";
import { Marker, InfoWindow } from "@react-google-maps/api";
export default class MapMarker extends React.Component {
state = {
mapMarker: null,
showingInfoWindow: false
};
onMarkerClick = (props) => {
this.setState({
showingInfoWindow: true
});
};
onInfoWindowClose = () =>
this.setState({
showingInfoWindow: false
});
onLoad = (mapMarker) => {
this.setState({
mapMarker
});
};
render() {
const { clusterer, markerData } = this.props;
return (
<Marker
clusterer={clusterer}
onLoad={this.onLoad}
position={{
lat: markerData.lat,
lng: markerData.lng
}}
clickable
onClick={this.onMarkerClick}
>
{this.state.showingInfoWindow === true && (
<InfoWindow
position={{
lat: markerData.lat,
lng: markerData.lng
}}
onCloseClick={this.onInfoWindowClose}
>
<div>
<p>hello</p>
</div>
</InfoWindow>
)}
</Marker>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With