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

React+Google Maps点击Marker仅显示单个信息窗口问题排查

问题分析与解决方案

嘿,这问题我一眼就看出来啦!你现在遇到的核心问题是所有Marker共享了同一个isOpen状态,导致只要这个状态切换,所有绑定它的InfoWindow都会一起弹出或关闭。

为什么会这样?

你的withStateHandlers里只维护了一个全局的布尔值isOpen,所有Marker的InfoWindow都依赖这个值做显示判断。不管你点击哪个Marker,触发的都是同一个onToggleOpen函数,切换的是全局的isOpen——那自然所有窗口都会跟着一起变化啦!

两种解决办法,任你选:

方法一:用状态记录当前打开的Marker标识

我们把单个布尔值换成存储“当前打开的Marker的唯一标识”(比如索引、item的ID),这样就能精准控制单个窗口的显示:

  1. 修改状态管理部分:
const MapWithAMakredInfoWindow = compose(
  // 把isOpen换成openMarkerId,初始值为null(表示没有窗口打开)
  withStateHandlers(() => ({ openMarkerId: null }), {
    onToggleOpen: ({ openMarkerId }) => (markerId) => ({
      // 如果点击的是已经打开的Marker,就关闭;否则打开它
      openMarkerId: openMarkerId === markerId ? null : markerId
    })
  }),
  withScriptjs,
  withGoogleMap
)(props => <GoogleMap
  defaultZoom={8}
  defaultCenter={{ lat: 44.8350088, lng: -0.5872689999999999 }}
>
  {this.state.PartenaireData.map(function (item, i) {
    if (item.coordinates.latitude && item.coordinates.longitude)
      return (
        <Marker
          position={{ lat: item.coordinates.latitude, lng: item.coordinates.longitude }}
          // 点击时传递当前Marker的索引(或者item.id,如果有唯一ID的话更稳妥)
          onClick={() => props.onToggleOpen(i)}
          key={i}
        >
          // 只有当openMarkerId等于当前索引时,才显示InfoWindow
          {props.openMarkerId === i && <InfoWindow onCloseClick={() => props.onToggleOpen(i)}>
            <div>
              <div>{item.titre}</div>
              <div>autre data</div>
            </div>
          </InfoWindow>}
        </Marker>)
  })}
</GoogleMap>);

方法二:封装独立的Marker组件(更简洁)

把每个Marker和对应的InfoWindow封装成单独的组件,让每个组件自己维护isOpen状态,彻底避免全局状态冲突:

  1. 创建独立组件:
// 单独的Marker组件,自己管理状态
const MarkerWithInfoWindow = ({ item }) => {
  const [isOpen, setIsOpen] = useState(false);

  const toggleOpen = () => {
    setIsOpen(!isOpen);
  };

  return (
    <Marker
      position={{ lat: item.coordinates.latitude, lng: item.coordinates.longitude }}
      onClick={toggleOpen}
    >
      {isOpen && <InfoWindow onCloseClick={toggleOpen}>
        <div>
          <div>{item.titre}</div>
          <div>autre data</div>
        </div>
      </InfoWindow>}
    </Marker>
  );
};
  1. 在地图组件中使用:
const MapWithAMakredInfoWindow = compose(
  withScriptjs,
  withGoogleMap
)(props => <GoogleMap
  defaultZoom={8}
  defaultCenter={{ lat: 44.8350088, lng: -0.5872689999999999 }}
>
  {this.state.PartenaireData.map(function (item, i) {
    if (item.coordinates.latitude && item.coordinates.longitude)
      // 直接用封装好的组件,每个组件独立管理状态
      return <MarkerWithInfoWindow item={item} key={i} />
  })}
</GoogleMap>);

两种方法的小提示:

  • 方法一适合需要在父组件控制窗口状态的场景(比如手动关闭所有窗口);
  • 方法二更简洁,组件职责更清晰,适合大多数普通场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:18:30