javascript - Google maps Infowindow ReactJS - Stack Overflow

very new to react. I'm using google-maps-react-api. I have two files. Index.js and MapMarker.js. I

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>
    );
  }
}

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>
    );
  }
}

Share Improve this question asked Jun 14, 2020 at 7:57 RobbenRobben 592 silver badges6 bronze badges 10
  • Do you get any errors? What have you tried to debug? Can you provide a working CodeSandbox? – MrUpsidown Commented Jun 14, 2020 at 10:24
  • Hey, no errors. I've been reading the documentation and it makes no reference to being able to open and close info windows by clicking markers. react-google-maps-api-docslify.app/#infowindow . I've changed the code a little and here is the sandbox link codesandbox.io/s/cocky-faraday-10kbs?file=/src/index.js . I have a cluster, markers and info boxes displaying permanantly and an alert when the marker is clicked but when I close the info box clicking the marker does not re open. Thanks – Robben Commented Jun 14, 2020 at 11:02
  • Do you need multiple info windows to be open at the same time? Otherwise, you should probably use only 1. – MrUpsidown Commented Jun 14, 2020 at 12:04
  • No, ideally just one. Click on a marker and one window displays which I can then close and open another one. Thanks so much for your help. – Robben Commented Jun 14, 2020 at 12:08
  • 1 That library is google-map-react which doesn’t support marker clustering and the one I’m using google-map-react-api which supports clustering but doesn’t seem to support opening into windows. Thanks again for your help. I might have to Compromise something for now until I can make my own. – Robben Commented Jun 14, 2020 at 12:18
 |  Show 5 more ments

1 Answer 1

Reset to default 3

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>
    );
  }
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745368892a4624708.html

相关推荐

  • javascript - Google maps Infowindow ReactJS - Stack Overflow

    very new to react. I'm using google-maps-react-api. I have two files. Index.js and MapMarker.js. I

    16小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信