3

I've got a project i'm working on where I use react google maps, however I've run into an issue where when I get the onBoundsChanged event and set state in the callback, it goes into a permanent loop of re rendering. I can only assume somehow that when the component re-renders after I call setState, it sets a new bounds and that will then re-trigger the callback and setState again, in form of an infinitely recursive loop.

import React from 'react'
import { compose, withProps, withStateHandlers, withState, withHandlers } from "recompose";
import {
  withScriptjs,
  withGoogleMap,
  GoogleMap,
  Marker
} from"react-google-maps";
import HouseDetails from './house/HouseDetails'
const { InfoBox } = require("react-google-maps/lib/components/addons/InfoBox");

class Map extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      zoom: 15,
      bounds: null    
    }
    this.map = React.createRef()
    this.onBoundsChanged = this.onBoundsChanged.bind(this)
    this.onZoomChanged = this.onBoundsChanged.bind(this)
  }
  componentWillReceiveProps(test){
  }
  onBoundsChanged(){
    this.setState({bounds: this.map.current.getBounds()}, ()=> console.log('update'))
    let bounds = this.map.current.getBounds()
    let realBounds = {lat:{west: bounds.ga.j, east: bounds.ga.l}, lon: {north: bounds.ma.j, south: bounds.ma.l}}
    console.log(realBounds) 

  }
  onZoomChanged(){
    this.setState({zoom: this.map.current.getZoom()})
  }
  componentDidUpdate(){
    console.log('hm')
  }
  render(){
    return (
    <GoogleMap
        defaultZoom={15}
        ref={this.map}
        onZoomChanged={this.onZoomChanged}
        onBoundsChanged={this.onBoundsChanged}
        center={{ lat: 21.493468, lng: -3.177552}}
        defaultCenter={this.props.center}>
    </GoogleMap>
    )
  }
}

export default withScriptjs(withGoogleMap(Map))

The code for the component that re-renders to infinity is above, it doesn't bug out so as long as I don't setState in the onBoundsChanged function. Is there any way around this?

Batzz
  • 422
  • 4
  • 12

2 Answers2

1

I am using react-google-maps.

if you want to update the marker on new position while dragging the map, you can use onBoundsChanged props

<GoogleMap
        ref={refMap}
        defaultZoom={13}
        defaultCenter={{ lat: center.lat, lng: center.lng }}
        onBoundsChanged={handleBoundsChanged}
        fullscreenControl={false}
        defaultOptions={defaultMapOptions}
        onDragEnd={handleDragend}
      >
        <Marker position={center} />
      </GoogleMap>

and in your handleBoundsChanged, you can update the center with new lat/lng

const handleBoundsChanged = () => {
    console.log("handleBoundsChanged")
    const lat = refMap.current.getCenter().lat()
    const lng = refMap.current.getCenter().lng()
    const mapCenter = {
      lat: lat,
      lng: lng,
    }
    setCenter(mapCenter); // move the marker to new location
  };

if you want to move the map to new lat/lng programatically, you can use panTo function in useEffect when the address is updated. This is needed when you input the address in search and you want your map and marker at new location

//on address update
  useEffect(() =>{
    console.log("props updates", props.address, props.locationName)
    if(props.address.source == 'searchbar'){
      console.log("in the searchbar props")
      const mapCenter = {
        lat: props.address.latitude,
        lng: props.address.longitude,
      }
      refMap.current.panTo(mapCenter) //move the map to new location
      setCenter(mapCenter) // move the marker to new location
    }
  },[props.address])
nawaz anjum
  • 81
  • 1
  • 2
0

I converted the class above from the docs compose examples, I must have screwed up somewhere because my mistake was very obvious, since on render the center is set for the GoogleMap object, all I had to do was have an initial state with a location, set the default state and then remove the 'center' prop from the component, this means that on re-render it does not pull it back to the center, and therefore does not re-trigger onBoundsChanged

Batzz
  • 422
  • 4
  • 12