当您使用Google Maps API点击 map 中的某个位置时,它会显示一个信息窗口,其中包含名称、地址和在Google Maps上查看该位置的链接.

enter image description here

有没有办法覆盖此事件并为其提供我自己的数据和样式?

到目前为止,我添加了一个onClick侦听器,它查找具有placeID属性的事件,获取该位置的数据,并将其显示在InfoWindow组件中.

但是,这并不妨碍打开默认窗口.它仍然开着,然后被我的盖住了.很管用,但并不完全是我想要达到的效果.

我要么希望完全阻止默认的事件处理程序显示,要么将我的更改直接应用到它,而不需要有这个单独的事件处理程序.

async function handleOnClick(event) {
    setContent(undefined);
    const latitude = event.latLng.lat();
    const longitude = event.latLng.lng();

    if (event.placeId) {
      const request = {
        placeId: event.placeId,
        fields: ['name', 'formatted_address', 'place_id', 'geometry', 'photo'],
      };

      const placesService = new google.maps.places.PlacesService(map);

      placesService.getDetails(request, (place, status) => {
        if (status === 'OK') {
          const info = (
            <InfoWindow
              position={{
                lat: place?.geometry?.location?.lat(),
                lng: place?.geometry?.location?.lng(),
              }}
              onCloseClick={() => setContent(undefined)}
            >
              <div>
                <h3>{place.name}</h3>
                <div className='photo-gallery'>
                  {place?.photos.map((photo) => {
                    return <img className='photo' src={photo.getUrl()} />;
                  })}
                </div>
              </div>
            </InfoWindow>
          );

          setContent(info);
        }
      });
    }
  }

我在使用@react-google-map/api库的Reaction中执行此操作

推荐答案

Use event.stop() method for POI click event to prevent the Info Window from showing while still processing the Place ID (EDITED)

MapOptions上有一个名为clickableIcons的选项,您可以将其设置为false,这将禁用默认POI图标/标记上的单击功能.

遗憾的是,这也会禁用您可以使用map.addListener()获得placeId个图标的功能

我的建议是让开发人员能够在单击时修改默认POI的内容.https://developers.google.com/maps/support#issue_tracker

但由于Google Maps API目前没有这个功能,一个解决办法(感谢Ops的 comments )是,一旦你在POI点击上有了地点ID,就用event.stop关闭事件.

下面是使用提供的代码OP应该如何工作:

创建一个Info窗口状态挂钩,以便稍后存储内容并生成组件.

const [infoWindow, setInfoWindow] = React.useState(null);

在onLoad回调定义中,判断位置ID是否可用.然后,如果为真,则触发event.stop()方法以阻止显示默认的信息窗口,并继续处理获取的带有Places API的Place详细信息的Place ID,并将这些数据放在您将在单击的POI图标上呈现的自定义Info窗口上.

const onLoad = React.useCallback(function callback(map) {
  map.addListener("click", (event) => {
    if (event.placeId) {
      // once the check for Place ID is done, 
      // fire the event.stop() here to prevent the default Info Window from showing
      event.stop();
      
      // Proceed in processing the Place Details request
      // and create the custom Info Window based on the fetched data
      const request = {
        placeId: event.placeId,
        fields: [
          "name",
          "formatted_address",
          "place_id",
          "geometry",
          "photo",
        ],
      };

      const placesService = new google.maps.places.PlacesService(map);

      placesService.getDetails(request, (place, status) => {
        if (status === "OK") {
          // store the Info Window component inside a variable,
          // This will be put inside the Info Window state hook later.
          const info = (
            <InfoWindow
              position={{
                lat: place?.geometry?.location?.lat(),
                lng: place?.geometry?.location?.lng(),
              }}
              onCloseClick={() => setInfoWindow(null)}
            >
              <div>
                <h3>{place.name}</h3>
                <div className="photo-gallery">
                  {place?.photos.map((photo) => {
                    return <img className="photo" src={photo.getUrl()} />;
                  })}
                </div>
              </div>
            </InfoWindow>
          );
          // Update the Info Window state hook here.
          setInfoWindow(info);
        }
      });
    }
  });
}, []);

然后,您只需将infoWindow状态挂钩放在GoogleMap组件中,以便在提供详细信息时显示Info窗口.

return isLoaded ? (
  <GoogleMap
    mapContainerStyle={containerStyle}
    center={center}
    zoom={15}
    onLoad={onLoad}
    onUnmount={onUnmount}
  >
    {infoWindow ? infoWindow : null}
  </GoogleMap>
) : (
  <></>
);

在经历了这一切之后,它应该看起来像这样:

enter image description here

这里有一个概念验证代码沙箱,你可以try 和发挥周围:https://codesandbox.io/p/sandbox/poi-click-infowindow-tfxjjw

注:使用您自己的API密钥

Reactjs相关问答推荐

我的组件在jsx文件中继续重新渲染

LocalStore未存储正确的数据

在react中向数组状态添加值时出错

StyleX中的多语言支持

使用REACT-RUTER-DOM链接仅更新一个搜索参数

Material-UI 和 React Hook 表单不记录值

更新对象状态的父数组时记住子组件

React useContext 的未定义返回值

提前输入错误:选项类型上不存在属性名称

如何将 DocuSign 控制台界面嵌入到 React 应用中

如何在不使用 Axios 的情况下将图像文件从 React.js 发送到 Spring Boot Rest API?

使用 React.lazy 调试 webpack 代码拆分

Select 建议后如何关闭 vscode 添加自动完成={}

用 jest 测试包裹在 redux 和 router 中的组件

刷新页面时状态改变问题

React Router v6 - 访问嵌套路由和处理手写 url 的正确方法

当状态改变时如何执行一些动作,但只针对第一次更新?

为什么重新渲染不会影响 setTimeout 的计数?

如何将 id 从页面传递到另一个页面?

在 Redux 中更新布尔状态时出错