谷歌地图Infowindow ReactJS

时间:2020-06-14 07:57:09

标签: javascript reactjs google-maps

非常新的反应。我正在使用google-maps-react-api。我有两个文件。 Index.js和MapMarker.js。它加载了一些位置点,并且已经加载了信息窗口。我可以关闭窗口,但是单击标记时它们不会重新打开。我的onCLick事件没有按我预期的那样工作。 我希望这种情况成为标记加载,然后单击它们以显示信息窗口,然后也可以关闭该窗口。我已经阅读了Github上的文档和问题,但是找不到相关信息。谢谢。

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

1 个答案:

答案 0 :(得分:0)

我通过您提供的codeandbox链接对MapMaker.js进行了一些更改。

首先,我添加了一个名为showingInfoWindow的状态,并分配了一个值false。这种状态将指示是否显示信息窗口。

然后,我添加了一个名为onMarkerClick的函数,该函数在每次单击标记时都会被调用。这会将showingInfoWindow的状态设置为true

接下来,我在MapMaker类的返回中添加了一个条件,该条件仅在showingInfoWindow设置为true时显示信息窗口。

然后,我添加了onInfoWindowClose函数,该函数将showingInfoWindow的状态重新设置为false

最后,我在中添加了onCloseClick参数,并调用了onInfoWindowClose函数。

您可以按照下面的代码片段进行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>
    );
  }
}