Hi all,
I am having an issue with making the InfoWindow shows up for the Mark I click on.
The expect behavior is when I click on the mark it will only shows information about that mark in the InfoWindow.
However, What I am getting now is that when I click on a marker all the marker shows up. And when I tried to close it rerender the app.
Any Idea how to fix this?
class VenuesMap extends Component {
constructor(props){
super(props);
this.state = {
zoom: 11,
isOpen: false
}
handleToggle = () => {
this.setState({
isOpen: !false
});
}
render() {
markers = venues.map((location, i) => {
const lat = location.venue.location.lat
const lng = location.venue.location.lng
const index = i + 1 ;
return (
<Marker
key={i}
position={{ lat: lat, lng: lng}}
label={index.toString()}
onClick={this.handleToggle}
>
{this.state.isOpen &&
<InfoWindow
onCloseClick={this.handleToggle}
>
<span>Something</span>
</InfoWindow>
}
</Marker>
)
})
const MapWithAMarker = withGoogleMap(props =>
<GoogleMap
defaultZoom={this.state.zoom}
defaultCenter={{ lat:Number(latCurrentLocation) || 40.7128, lng:
Number(lngCurrentLocation) || -74.0060}}
>
{markers}
{userMarkers}
</GoogleMap>
);
const googleMap = <MapWithAMarker
containerElement={<div style={{ height: this.props.containerElement }} />}
mapElement={<div style={{ height: this.props.mapElement}} />}
/>
return (
<div>
{googleMap}
</div>
)
}
}
export default connect(stateToProps)(VenuesMap)


I fixed. I replaced with Marker and InfoWindow to its component.
import React, {Component} from 'react';
import { Marker, InfoWindow } from "react-google-maps";
class InfoWindowMap extends Component {
constructor(props){
super(props);
this.state = {
isOpen: false
}
}
handleToggleOpen = () => {
this.setState({
isOpen: true
});
}
handleToggleClose = () => {
this.setState({
isOpen: false
});
}
render() {
return (
<Marker
key={this.props.index}
position={{ lat: this.props.lat, lng: this.props.lng}}
label={this.props.index.toString()}
onClick={() => this.handleToggleOpen()}
>
{
this.state.isOpen &&
<InfoWindow onCloseClick={this.props.handleCloseCall}>
<h1>{this.props.location.venue.name}</h1>
</InfoWindow>
}
</Marker>
)
}
}
export default InfoWindowMap;
Hi @spaceforestchu - is this the complete code for the fix? I tried to replicate your fix but couldn't seem to do it. Is there a separate component for GoogleMap? If so, can you post your entire fix?
Thanks for posting the solution!
@hrashid sorry I just saw this.
I made an info window component.
lng: this.props.lng
}} label={this.props.index.toString()}
onClick={() => this.handleClicks(this.props.venueID)}
>
{
this.state.isOpen &&
<InfoWindow onCloseClick={() => this.setState({isOpen: false})}>
<div>
<h4>{this.props.location.venue.name}</h4>
<img src={`${venuePhoto}`}/>
<span>{number}</span>
</div>
</InfoWindow>
}
</Marker>
then I put the infoWindowMap component in sindei google map component.
<InfoWindowMap
key={index}
lat={lat}
lng={lng}
index={index}
location={location}
indexValue={index}
venueID={venueID}
/>
You can find the code in my github the project is called your 4 square. Let me know if you need any help.
I have same problem and I solved like following..
class GoogleMapBox extends React.Component{
state = {
position : null
}
handleToggleOpen(item){
this.setState({
position : {
lat : item.lat,
lng : item.lng
}
})
}
render(){
return (
<GoogleMap ....>
{markers.map((item) => (
<Marker
key={this.props.index}
position={{ lat: this.props.lat, lng: this.props.lng}}
label={this.props.index.toString()}
onClick={() => this.handleToggleOpen(item)}
/>
)}
{this.state.position &&
<InfoWindow position={this.state.position}>
<h1>{this.props.location.venue.name}</h1>
</InfoWindow>
}
</GoogleMap>
)
}
}
(this code is not exact. cause I quickly typed it in this editor)
this way is
It works good. I recommend this way.
my solution below
try this:
{props.nhatro.map((nhatro, index) =>
<Marker
key={index}
options={{icon: 'https://i.imgur.com/9G5JOp8.png'}}
position={nhatro}
onClick={()=>{ props.showInfo(index)} }
>
{ (props.showInfoIndex == index ) &&
<InfoWindow onCloseClick={props.onToggleOpen}>
<div>
<div>nhĂ trá» cho thuĂȘ</div>
<div >1.500.000Ä</div>
</div>
</InfoWindow>}
</Marker>
)}
and then :
showInfo(a){
setState({showInfoIndex: a })
}
@nguyenvanphuc2203 where did you put your ShowInfo ?

@nguyenvanphuc2203 Thanks for your code. However, after opening an info window and closing it once. The info window will not be able to show up again.
So below is the quick fix, I just added an additional condition for showing the info window (ie . props.isOpen).
{locationMarkers && locationMarkers.map((marker) =>
<Marker key={marker.index} position={marker.position} onClick={() => { props.showInfo(marker.index) }}>
{(props.isOpen && props.showInfoIndex == marker.index) &&
<InfoWindow onCloseClick={props.onToggleOpen}>
<div>
{marker.info}
</div>
</InfoWindow>}
</Marker>
)}
If there is another better fix, please let me know!
nice man :D
@nguyenvanphuc2203 @pttse
IMO, the easiest and the right way is to 'reset' showInfo prop on close.
BTW, you could use only one function that handles opening and closing InfoWindow.
My code looks like this:
withStateHandlers(() => ({
isOpen: false,
infoIndex: null
}), {
showInfo: ({ isOpen, infoIndex }) => (index) => ({
isOpen: infoIndex !== index || !isOpen,
infoIndex: index
})
})
<Marker onClick={() => props.showInfo(marker.index)}>
{(props.isOpen && props.infoIndex === marker.index) &&
<InfoWindow onCloseClick={props.showInfo}>
<span>{marker.info}</span>
</InfoWindow>}
</Marker>
**Hi guys!
Can someone help me?
I have this error: **

in the following peace of code:
import React from 'react'
import PropTypes from 'prop-types'
import template from 'modules/template'
import OverlayView from './CustomOverlayView'
import IconButton from '@material-ui/core/IconButton';
import Place from '@material-ui/icons/Place'
import blueGrey from '@material-ui/core/colors/blueGrey';
import red from '@material-ui/core/colors/red';
import { getColors } from 'utils/status'
import PersonalizedInfoWindow from './PersonalizedInfoWindow'
const disabledColor = blueGrey[500]
const DefaultIcon = ({
status,
isEnabled = true,
isSelected = false,
...other
}) => {
const { primary = red[500] } = getColors(status)
let color = (!isEnabled && !isSelected) ? disabledColor : primary
const iconStyle = { color }
return
}
class CustomOverlayMarker extends React.Component {
constructor(props) {
super(props)
this.state = {
isOpen: false
}
}
handleMouseOver = () => {
this.setState({
isOpen: true
})
}
handleMouseOver = () => {
this.setState({
isOpen: false
})
}
render() {
let markerIcon
if (this.props.children) {
markerIcon = React.cloneElement(this.props.children, this.props.size)
} else {
markerIcon = <DefaultIcon {...this.props} />
}
let infoWindow = null
if (this.state.isOpen) {
infoWindow = <PersonalizedInfoWindow position={this.props.position} label={this.props.label} />
}
// For some reason the general provider is not inherited in the OverlayView :-S
const MuiThemeProvider = template.components.ThemeProvider
return (
<OverlayView
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
position={this.props.position}
getPixelPositionOffset={() => ({ x: -this.props.size / 2, y: -this.props.size })}
>
<MuiThemeProvider>
<IconButton
tooltip={this.props.label}
onClick={this.props.onClick}
onMouseOver={this.handleMouseOver()}
onMouseOut={this.handleMouseOver()}
>
{markerIcon}
{infoWindow}
</IconButton>
</MuiThemeProvider>
</OverlayView>
)
}
}
CustomOverlayMarker.propTypes = {
size: PropTypes.number,
label: PropTypes.string,
position: PropTypes.object,
isEnabled: PropTypes.bool,
isSelected: PropTypes.bool,
onClick: PropTypes.func
}
export default CustomOverlayMarker
Does someone know how to avoid this??
```
handleMouseOver = () => {
if (!this.state.isOpen) {
this.setState({
isOpen: true
})
}
}
handleMouseOver = () => {
if (this.state.isOpen) {
this.setState({
isOpen: false
})
}
}
```
The solution was as simple as adding this:
onClick={this.props.onClick}
onMouseOver={()=>this.handleMouseOver()}
onMouseOut={()=>this.handleMouseOver()}
>
My solution:
withStateHandlers(() => ({
isOpen: false,
markerIndex: 0
}), {
onToggleOpen: ({ isOpen }) => (index) => ({
isOpen: !isOpen,
markerIndex: index
})
})
<Marker
onClick={ ()=> {props.onToggleOpen(index} }>
{ props.isOpen && props.markerIndex === index &&
<InfoWindow onCloseClick={props.onToggleOpen}>
<div>Working</div>
</InfoWindow>
}
</Marker>
The infoWindow corresponding to the marker doesn't get shown up when i click on the marker. The markers keep refreshing when i click on them. I can't figure out what i've done wrong. Can anybody help me with this ?
import { GoogleApiWrapper, Map, Marker, InfoWindow } from "google-maps-react";
import React, { useState } from "react";
import { GOOGLE_API_KEY } from "../../../../../utils/environment";
import styles from "./../../../wrappers/widgetsWrapper.module.scss";
const mapStyles = {
width: "100%",
height: "100%"
};
const GoogleMaps = props => {
const [infoOpen, setInfoOpen] = useState(null);
const { chartData } = props;
const handleToggle = (id) => {
setInfoOpen(id)
}
const formatData = (chartData) => {
chartData.map((place, index) => {
place.id = "id" + index
})
const data = chartData
return data
}
// const mapDetails = formatData(chartData.data.mapData)
// console.log("mapDetails : ", mapDetails);
const mapDetails = [
{
"label": "Lady Gray Gourmet Medibles",
"lat": 61.217835,
"lng": -149.88037
},
{
"label": "Lady Gray Gourmet Medibles",
"lat": 64.837205,
"lng": -147.806626
},
{
"label": "Glacier Extracts",
"lat": 64.837205,
"lng": -147.806626
},
{
"label": "Baked Alaska",
"lat": 61.191401,
"lng": -149.912576
},
]
return (
<React.Fragment>
<div className={styles.dashboardWidgetCard}>
<Map
google={props.google}
zoom={4}
style={mapStyles}
initialCenter={{ lat: 61.217835, lng: -149.88037 }}
>
{mapDetails.map((mapData, index) => (
<Marker
key={index}
position={{ lat: mapData.lat, lng: mapData.lng }}
onClick={() => { handleToggle(index) }}
>
{(infoOpen == index) &&
<InfoWindow>
<h3>helooo</h3
</InfoWindow>
}
</Marker>
))}
</Map>
</div>
</React.Fragment>
);
};
export default GoogleApiWrapper({
apiKey: GOOGLE_API_KEY
})(GoogleMaps);
@SenelithPerera
The repo of this project is unmaintained more than a year, and we had build new version https://www.npmjs.com/package/@react-google-maps/api
We had rewrite it to TypeScript, and updating it frequently: https://github.com/JustFly1984/react-google-maps-api/tree/master/packages/react-google-maps-api
You can enjoy autocomplete.
You can see our docs: https://react-google-maps-api-docs.netlify.com/
Also a lot of examples: https://react-google-maps-api-gatsby-demo.netlify.com/ https://github.com/JustFly1984/react-google-maps-api/tree/master/packages/react-google-maps-api-gatsby-example/src/examples
The bundle size is much smaller: https://bundlephobia.com/result?p=@react-google-maps/api@1.7.5
Enjoy!
@JustFly1984 Just after posting this question, I found your github repo. The issue was fixed.
@nguyenvanphuc2203 Thanks for your code. However, after opening an info window and closing it once. The info window will not be able to show up again.
So below is the quick fix, I just added an additional condition for showing the info window (ie . props.isOpen).
{locationMarkers && locationMarkers.map((marker) => <Marker key={marker.index} position={marker.position} onClick={() => { props.showInfo(marker.index) }}> {(props.isOpen && props.showInfoIndex == marker.index) && <InfoWindow onCloseClick={props.onToggleOpen}> <div> {marker.info} </div> </InfoWindow>} </Marker> )}If there is another better fix, please let me know!
Could you please share the all the code. I am trying with this but getting some issues
@mahendragurav2
The repo of this project is unmaintained more than a year, and we had build new version https://www.npmjs.com/package/@react-google-maps/api
We had rewrite it to TypeScript, and updating it frequently: https://github.com/JustFly1984/react-google-maps-api/tree/master/packages/react-google-maps-api
You can enjoy autocomplete.
You can see our docs: https://react-google-maps-api-docs.netlify.com/
Also a lot of examples: https://react-google-maps-api-gatsby-demo.netlify.com/ https://github.com/JustFly1984/react-google-maps-api/tree/master/packages/react-google-maps-api-gatsby-example/src/examples
The bundle size is much smaller: https://bundlephobia.com/result?p=@react-google-maps/api@1.7.7
Our Spectrum community: https://spectrum.chat/react-google-maps
Enjoy!
Here is a complete solution InfoWindow shows. i have also attached the link you can see for more understanding.. https://codesandbox.io/s/quizzical-hermann-5ehs7
import React, { Component } from "react";
import { Map, InfoWindow, Marker, GoogleApiWrapper } from "google-maps-react";
export class MapContainer extends Component {
state = {
activeMarker: {},
selectedPlace: {},
showingInfoWindow: false
};
onMarkerClick = (props, marker) =>
this.setState({
activeMarker: marker,
selectedPlace: props,
showingInfoWindow: true
});
onInfoWindowClose = () =>
this.setState({
activeMarker: null,
showingInfoWindow: false
});
onMapClicked = () => {
if (this.state.showingInfoWindow)
this.setState({
activeMarker: null,
showingInfoWindow: false
});
};
render() {
if (!this.props.loaded) return <div>Loading...</div>;
return (
<Map
className="map"
google={this.props.google}
onClick={this.onMapClicked}
style={{ height: "100%", position: "relative", width: "100%" }}
zoom={13}
>
<Marker
name="Marker 1"
onClick={this.onMarkerClick}
position={{ lat: 37.778519, lng: -122.40564 }}
/>
<Marker
name="Marker 2"
onClick={this.onMarkerClick}
position={{ lat: 37.759703, lng: -122.428093 }}
/>
<Marker name="Marker 3" onClick={this.onMarkerClick} />
<InfoWindow
marker={this.state.activeMarker}
onClose={this.onInfoWindowClose}
visible={this.state.showingInfoWindow}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
</div>
</InfoWindow>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: "",
version: "3.38"
})(MapContainer);
Most helpful comment
my solution below
try this:
and then :