Search code examples
reactjsreact-google-maps

Unable to render the Google map on state change


I am trying to change the state of salesPropertyInfoWindowIn by assigning an array salesPropertyInfoWindowOut that is defined globally.

initial value of

salesPropertyInfoWindowIn : 
[false,false,false,false,false,false,false,false,false,false]

onMarkerClick method changes the value of index passed as an parameter then assigns the value in salesPropertyInfoWindowIn. However, this doesn't rerender the map. Please help me by suggesting some solution.

const MapWithAMarkerClusterer = compose(
withProps({
  googleMapURL:
    "https://maps.googleapis.com/maps/api/js?key=AIzaSyDlMypBHZKOOgwp7PBHrQSvf75Y1sM2gnU&v=3.exp&libraries=geometry,drawing,places",
  loadingElement: <div style={{ height: `100%` }} />,
  containerElement: <div style={{ height: `390px` }} />,
  mapElement: <div style={{ height: `100%` }} />
}),

withStateHandlers(
  () => ({
    salesPropertyInfoWindowIn: salesPropertyInfoWindowOut,
    isOpen: false,

  }),
  {
    onToggleOpen: ({isOpen}) => () => ({
      isOpen: !isOpen
    }),
    onMarkerClick: ({salesPropertyInfoWindowIn}) => (marker, i) => (
      salesPropertyInfoWindowOut[i] = !salesPropertyInfoWindowOut[i], 
      {salesPropertyInfoWindowIn: salesPropertyInfoWindowOut}
      )
  }),
withScriptjs,
withGoogleMap)(props => (
<GoogleMap
  defaultZoom={15}
  defaultCenter={
    home.currentProperty != null
      ? {
          lat: parseFloat(home.currentProperty.property.location.lat),
          lng: parseFloat(home.currentProperty.property.location.lon)
        }
      : ""
  }
>
  <MarkerClusterer averageCenter enableRetinaIcons gridSize={10}>
    {home.propSalesData != undefined || home.propSalesData != null
      ? props.markers.map((marker, i) => (
          <Marker
            icon={salesPropertyMarkerImage}
            onClick={() => props.onMarkerClick(marker, i)}
            key={i}
            position={{
              lat: parseFloat(marker.location.lat),
              lng: parseFloat(marker.location.lon)
            }}
          >
           {(props.salesPropertyInfoWindowIn[i] == true) ? 
             (console.log('Inside', props.salesPropertyInfoWindowIn[i]),
             <InfoWindow>
               <text>
                 {home.propSalesData[i].agent.name != undefined ||
                 home.propSalesData[i].agent.name != null
                   ? "Agent: " + home.propSalesData[i].agent.name
                   : "Purchaser: " +
                     home.propSalesData[i].saleParticipants
                       .purchasersSummary}
               </text>
             </InfoWindow>
           ) : ""} 
           </Marker>
        ))
      : ""}

Solution

  • You can try storing the index of the clicked marker, instead of using the 2 arrays salesPropertyInfoWindowIn / salesPropertyInfoWindowOut.

    onMarkerClick(index) {
      this.setState({clickedMarkerIndex: index})
    }
    

    Then, to render InfoWindows only on clicked markers:

    {props.markers.map((marker, index) => {
      <Marker onClick={() => props.onMarkerClick(index)}>
        {props.clickedMarkerIndex === index &&
          <InfoWindow> etc etc
        }
      </Marker>
    })