0

I am currently using react-google-maps and I am able to display the marker and InfoWindow correctly by clicking on the marker (from the map or from the list). But once I click on a marker to open, the previous InfoWindow stays open even when I select a new one.

react-google-maps-screenshot

I am able to close the InfoWindow if I click on the 'x' or marker from list. But I'm not sure how to close other InfoWindows automatically and only open the current marker's InfoWindow.

I have looked at several similar questions to get an idea: When displaying multiple markers on a map, how to open just one info window, when clicking on a marker?, React-Google-Map multiple Info window open .

But I'm still having trouble with passing and checking for unique marker so that only the InfoWindow which matches the marker ID is displayed.

class MarkerInfoList extends Component {

  constructor(props){
    super(props);

    this.state = {
      isOpen: false
    };
  }

  handleToggleOpen = (markerId) => {
    this.setState({ 
      isOpen: true
    });
  }

  handleToggleClose = (markerId) => {
    this.setState({
      isOpen: false
    });
  }


render() {

  const isOpen = this.state.isOpen;

  return (

    <div>
      {this.state.isOpen ? (
        <ul>
          <li onClick={() => this.handleToggleClose()}>{this.props.venue}</li>

          <Marker
            key={this.props.index}
            id={this.props.index}
            position={{ lat: this.props.lat, lng: this.props.lng}}
            defaultAnimation={google.maps.Animation.DROP}
            onClick={() => this.handleToggleOpen(this.props.index)}>

            <InfoWindow 
                id = {this.props.index}
                onCloseClick={() => this.setState({isOpen: false})}>
                <div key={this.props.index}>
                  <h4>{this.props.venue}</h4>
                </div>
            </InfoWindow>  
          </Marker>
        </ul>

      ) : (

        <ul>
          <li onClick={() => this.handleToggleOpen()}>{this.props.venue}</li> 
        </ul>

      )
    }

  </div>

    )
  }
}

export default MarkerInfoList;
teresa
  • 356
  • 5
  • 21

1 Answers1

1

I wanted to toggle individual windows but also needed to know if the locations were "active" on a parent component. So in the parent component I have state the with an active key. I am passing that down to the Map as activeKey component as well as the initial list with all the location data as locations.

 <GoogleMap defaultZoom={16} defaultCenter={this.state.currentLocation}>
        {this.props.locations.map((location, i) => (
          <Marker
            key={location.key}
            position={{
              lat: location.latitude,
              lng: location.longitude
            }}
            onClick={() => {
              this.props.toggleLocationsActive(location.key);
              // this.setCurrentLocation(location.latitude, location.longitude);
            }}
          >
                      {location.key === this.props.activeKey && (
          <InfoWindow onCloseClick={props.onToggleOpen}>
            <div>
              {location.orgName}
              {location.orgName !== location.programName &&
                "/" + location.programName}
            </div>
          </InfoWindow>
        )}
          </Marker>
        ))}
      </GoogleMap>

In the parent component I had state = {activeKey: ""} and the following method:

  toggleLocationsActive = locationKey => {
    this.setState({
      activeKey: locationKey
    });
  };

Both are are passed down in props:

   <Map
            activeKey={this.state.activeKey}
            toggleLocationsActive={this.toggleLocationsActive}
          />

Please note that I if you don't require this state to exist in the parent component you could do this within the map component.

fstep
  • 673
  • 1
  • 8
  • 13
  • I understand comparing the "active" location with the list of locations but how do you set the state from parent component to pass down? If I start with a list of marker, when user clicks on the marker, I set the specific marker location as active and pass that into child component? – teresa May 22 '18 at 19:12
  • Edited my answer above to answer your question. – fstep May 22 '18 at 23:51
  • 1
    I was able to get the info window to open one at a time thanks to your explanation. But every time I click on the marker, the map re-renders, and the correct info window is open. Wondering if your map also re-renders? – teresa May 23 '18 at 21:09
  • 1
    It is making a new API call and reloading the map in my app as well. – fstep May 24 '18 at 01:56