You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Google PlacesService的getDetails()函数使用报错求助

修复React中Google PlacesService getDetails()的使用问题

看起来你遇到的错误是因为在React的JSX渲染流程里直接调用getDetails()导致的,还有几个小细节需要调整,我来一步步帮你解决:

问题根源

  1. 错误的调用时机:你在Marker的JSX内部直接执行service.getDetails(),这会导致每次组件渲染都触发API调用,而且Google Places Service的回调会和React的状态更新不同步——当回调执行时,对应的InfoWindow DOM元素可能还没准备好,就会出现Cannot read property 'innerHTML' of undefined的错误。
  2. 参数重名冲突:回调函数里的第一个参数你命名为marker,和外层循环的marker变量重名了,这会导致你在回调里访问的不是原来的标记数据,而是API返回的地点对象,容易引发逻辑混乱。
  3. 未绑定状态数据:InfoWindow的内容是硬编码的,没有和获取到的地点详情数据绑定,即使API调用成功,也无法展示正确信息。

修复方案

步骤1:添加状态管理地点详情和激活标记

在你的组件里添加React状态,用来存储选中地点的详情和当前激活的标记索引:

import { useState, useEffect, useRef } from 'react';

// ...
const [activeKey, setActiveKey] = useState(null);
const [selectedPlace, setSelectedPlace] = useState(null);
const placesServiceRef = useRef(null);

步骤2:初始化PlacesService实例

在组件挂载时初始化PlacesService,避免重复创建实例:

useEffect(() => {
  // 创建一个隐藏的DOM元素用于初始化PlacesService(Google API要求必须绑定DOM元素)
  const service = new google.maps.places.PlacesService(document.createElement('div'));
  placesServiceRef.current = service;
}, []);

步骤3:把getDetails调用移到点击事件里

创建单独的点击处理函数,在Marker被点击时再触发API请求:

const handleMarkerClick = (index, placeId) => {
  setActiveKey(index);
  setSelectedPlace(null); // 重置之前的详情数据

  if (!placesServiceRef.current) return;

  placesServiceRef.current.getDetails({ placeId }, (place, status) => {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      setSelectedPlace(place);
    }
  });
};

步骤4:修改JSX渲染逻辑

更新Marker和InfoWindow的代码,绑定状态数据:

{markers.map((marker, i) => (
  <Marker
    {...marker}
    key={i}
    position={marker.location}
    title={marker.title}
    place_id={marker.place_id}
    id={i}
    icon={`http://www.serwisstron.pl/icons/${marker.type}.png`}
    onClick={() => handleMarkerClick(i, marker.place_id)}
    animation={google.maps.Animation.DROP}
  >
    {i === activeKey && (
      <InfoWindow 
        onCloseClick={() => {
          setActiveKey(null);
          setSelectedPlace(null);
        }}
      >
        <div id="details">
          <strong>{selectedPlace?.name || marker.title}</strong>
          <br />
          <span>Address:</span>
          <span>{selectedPlace?.formatted_address || 'Loading address...'}</span>
          {/* 可以按需添加更多地点详情字段,比如电话、评分、营业时间等 */}
        </div>
      </InfoWindow>
    )}
  </Marker>
))}

关键说明

  • 把API调用移到用户点击事件里,确保只有在交互时才触发请求,避免不必要的渲染和API调用浪费。
  • 使用React状态管理地点详情,当数据更新时组件会自动重新渲染,InfoWindow就能展示最新的内容。
  • 用?.可选链操作符避免数据未加载时出现undefined错误,提升页面稳定性。

这样修改后,你的代码应该就能正常获取并展示地点详情了,不会再出现之前的DOM相关错误。

内容的提问来源于stack exchange,提问作者Iwona Hajczewska

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:48