Google 地图 API,标记 onClick 侦听器未按预期工作

Google Maps API, Marker onClick listener not working as intended

现在我正在尝试制作一张地图,显示印度尼西亚的所有医院(以及稍后关于 covid 病例的信息),到目前为止,我已经能够从 json 文件中成功获取位置并将其映射到地图上。我的地图有一个按钮,如果你点击它,印度尼西亚的所有医院都会作为标记显示在地图上。我现在想做的是当用户单击特定标记时弹出医院名称的信息窗口。

我是如何尝试接近它的: 为所有医院标记创建一个状态布尔数组,以查看医院是否已被单击 如果已单击医院,则输出带有医院名称的信息窗口。

问题: 似乎当我单击按钮以显示印度尼西亚的所有医院时,它会将状态布尔数组更新为全部为真。我不确定为什么会这样,当我点击一个特定的标记时,状态数组没有改变。

如果您需要完整代码,这是我的 git 存储库:https://github.com/ktanojo17505/google-map-react

这是我的状态:

state = { 
    address: "",
    city: "",
    area: "",
    state: "",
    zoom: 11,
    height: 400,
    mapPosition: {
      lat: 0,
      lng: 0
    },
    markerPosition: {
      lat: 0,
      lng: 0
    },
    placeHospitals: false,
    Hospitals: [],
    didClickHospital: []
  };

这是我的构造函数:

constructor(props) {
    super(props);
    var HospitalLocations = [];
    var clickHospital = [];
    var position;
    var hospitalName;
    var id;
    for (let index = 0; index < HospitalData.hospitals.length; ++index) {
      id = index;
      var latitude = HospitalData.hospitals[index].latitude;
      var longitude = HospitalData.hospitals[index].longitude;
      position = { latitude, longitude };
      hospitalName = HospitalData.hospitals[index].nama;
      var entry = { id, position, hospitalName };
      HospitalLocations.push(entry);
      clickHospital.push(false);
    }
    this.state.Hospitals = HospitalLocations;
    this.state.didClickHospital = clickHospital;
  }

这是我的return

return (
      <div style={{ padding: "1rem", margin: "0 auto", maxWidth: 1000 }}>
        <h1>Google Maps Basic</h1>
        <Descriptions bordered>
          <Descriptions.Item label="City">{this.state.city}</Descriptions.Item>
          <Descriptions.Item label="Area">{this.state.area}</Descriptions.Item>
          <Descriptions.Item label="State">
            {this.state.state}
          </Descriptions.Item>
          <Descriptions.Item label="Address">
            {this.state.address}
          </Descriptions.Item>
        </Descriptions>
        <MapWithAMarker
          googleMapURL={
            "https://maps.googleapis.com/maps/api/js?key=" +
            config.GOOGLE_API_KEY +
            "&v=3.exp&libraries=geometry,drawing,places"
          }
          loadingElement={<div style={{ height: `100%` }} />}
          containerElement={<div style={{ height: `400px` }} />}
          mapElement={<div style={{ height: `100%` }} />}
        />
        <div style={{ marginTop: "2.5rem" }}>
          <Button onClick={this.placeHospitals}>Hospitals</Button>
        </div>
      </div>
    );

带标记的地图

const MapWithAMarker = withScriptjs(
      withGoogleMap(props => (
        <div>
          <GoogleMap
            defaultZoom={this.state.zoom}
            defaultCenter={{
              lat: this.state.mapPosition.lat,
              lng: this.state.mapPosition.lng
            }}
            options={options}
            onClick={this.placeMarker}
          >
            <Marker
              draggable={true}
              onDragEnd={this.onMarkerDragEnd}
              position={{
                lat: this.state.markerPosition.lat,
                lng: this.state.markerPosition.lng
              }}
            >
              <InfoWindow>
                <div>{this.state.address}</div>
              </InfoWindow>
            </Marker>
            {this.state.placeHospitals &&
              this.state.Hospitals.map(hospitalLoc => ( // Place the locations if Hospitals Button is clicked 
                <Marker
                  draggable={false}
                  position={{
                    lat: hospitalLoc.position.latitude,
                    lng: hospitalLoc.position.longitude
                  }}
                  key={hospitalLoc.id}
                  onClick={this.clickHospital(hospitalLoc.id)} // Change the state of the Hospital InfoWindow 
                >
                  {/* {this.state.didClickHospital[index] && ( // If true output an infowindow of the hospital name 
                    <InfoWindow>
                      <div>{hospitalLoc.name}</div>
                    </InfoWindow>
                  )} */}
                </Marker>
              ))}
            <AutoComplete
              style={{
                width: "100%",
                height: "40px",
                paddingLeft: 16,
                marginTop: 2,
                marginBottom: "2rem"
              }}
              types={["(regions)"]}
              onPlaceSelected={this.onPlaceSelected}
            />
          </GoogleMap>
        </div>
      ))
    );

点击医院

clickHospital = id => {
    console.log("clicked");
    // var tempClickHospital = this.state.didClickHospital;
    // console.log(tempClickHospital[index]);
    // tempClickHospital[index] = !tempClickHospital[index];
    // console.log(tempClickHospital[index]);
    // this.setState({ didClickHospital: tempClickHospital });
    // console.log(this.state.didClickHospital);
  };

这是我的代码的输出(在点击医院之前)1

这是我的代码的输出(点击医院后)2

如果有人能指出我做错了什么,那将很有帮助,谢谢!

您可以直接映射 json 文件中的每个数据,以创建一个包含 <InfoWindow> 的单独 <Marker>

这里有一个 working sample code 和下面关于如何执行此操作的代码片段:

import React, { Component } from "react";
import {
  withGoogleMap,
  GoogleMap,
  Marker,
  InfoWindow
} from "react-google-maps";
//import the json data of your hospital info
import data from "./data.json";
import "./style.css";

class Map extends Component {
  constructor(props) {
    super(props);

    this.state = {
      hospitalId: "",
      addMarkerBtn: false
    };
  }
  addMarkerFunction = () => {
    this.setState({
      addMarkerBtn: true
    });
  };

  handleToggleOpen = id => {
    this.setState({
      hospitalId: id
    });
  };

  render() {
    const GoogleMapExample = withGoogleMap(props => (
      <GoogleMap
        defaultCenter={{ lat: -6.208763, lng: 106.845599 }}
        defaultZoom={16}
      >
        {this.state.addMarkerBtn === true &&
          data.map(hospital => (
            <Marker
              key={hospital.id}
              position={{ lat: hospital.lat, lng: hospital.lng }}
              onClick={() => this.handleToggleOpen(hospital.id)}
            >
              {this.state.hospitalId === hospital.id && (
                <InfoWindow
                  onCloseClick={this.props.handleCloseCall}
                  options={{ maxWidth: 100 }}
                >
                  <span>{hospital.id}</span>
                </InfoWindow>
              )}
            </Marker>
          ))}
      </GoogleMap>
    ));

    return (
      <div>
        <button id="addMarker" onClick={() => this.addMarkerFunction()}>
          Add Marker
        </button>
        <GoogleMapExample
          containerElement={<div style={{ height: `500px`, width: "500px" }} />}
          mapElement={<div style={{ height: `100%` }} />}
        />
      </div>
    );
  }
}

export default Map;