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

React Google Map点击Marker弹出全部InfoWindow问题求助

Fix: All InfoWindows Open on Single Marker Click

Hey there! I’ve run into this exact issue before with react-google-maps—let’s get your InfoWindows behaving properly so only the clicked Marker’s window pops up.

The Root of the Problem

Your current state setup uses a single isOpen boolean and a markerId, but your condition for rendering the InfoWindow is incorrect:

{props.isOpen[props.markerId] && <InfoWindow ... />}

isOpen is a boolean, not an object, so this check doesn’t work as intended. Instead, you need to verify two things:

  • The isOpen flag is true
  • The current Marker’s ID matches the markerId stored in state

Fixing the State Handler

First, update your onToggleOpen handler to correctly toggle the state based on whether the clicked Marker is already open:

withStateHandlers(() => ({ isOpen: false, markerId: '' }), {
  onToggleOpen: ({ isOpen, markerId }) => (clickedMarkerId) => ({
    // If clicking the same marker, close it; else open the new one
    isOpen: markerId !== clickedMarkerId || !isOpen,
    markerId: clickedMarkerId
  })
}),

Fixing the InfoWindow Render Condition

Next, adjust the condition in your Marker loop to only render the InfoWindow when the current Marker’s ID matches the state’s markerId and isOpen is true:

{props.isOpen && props.markerId === company.company_name && (
  <InfoWindow onCloseClick={() => props.onToggleOpen(company.company_name)}>
    <p>Test</p>
  </InfoWindow>
)}

Full Corrected Code

Here’s the complete updated component with both fixes applied:

const MapWithAMarkerClusterer = compose(
  withProps({
    googleMapURL: "MY KEY",
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `400px` }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  withHandlers({
    onMarkerClustererClick: () => (markerClusterer) => {
      const clickedMarkers = markerClusterer.getMarkers()
    }
  }),
  withStateHandlers(() => ({ isOpen: false, markerId: '' }), {
    onToggleOpen: ({ isOpen, markerId }) => (clickedMarkerId) => ({
      isOpen: markerId !== clickedMarkerId || !isOpen,
      markerId: clickedMarkerId
    })
  }),
  withScriptjs,
  withGoogleMap
)(props => 
  <GoogleMap
    defaultZoom={4}
    defaultCenter={{ lat: -23.696248, lng: 133.880731 }}
  >
    <MarkerClusterer
      onClick={props.onMarkerClustererClick}
      averageCenter
      enableRetinaIcons
      gridSize={60}
    >
      {props.companies.map(company => (
        <span key={company.company_name}>
          <Marker
            position={company.google_maps.geometry_location}
            onClick={() => props.onToggleOpen(company.company_name)}
          >
            {props.isOpen && props.markerId === company.company_name && (
              <InfoWindow onCloseClick={() => props.onToggleOpen(company.company_name)}>
                <p>Test</p>
              </InfoWindow>
            )}
          </Marker>
        </span>
      ))}
    </MarkerClusterer>
  </GoogleMap>
);

Quick Notes

  • The onCloseClick for InfoWindow now passes the current Marker’s ID to onToggleOpen, which will close the window properly.
  • The state logic ensures that clicking the same Marker twice will toggle it closed, and clicking a different Marker will switch the open InfoWindow to the new one.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:41:13