3

I have a single page application, using reactjs and react-router. I developed a maps component, and of course with google maps have a memory leak going from screen to screen if I try and cleanup the map on component did mount and rebuild it on component did mount. so I tried this approach:

What is the proper way to destroy a map instance

and re-using the map instance and the node combined with excessive measures to clean things up works well and stabilizes things. For cleanup, I

  • call clearInstanceListeners on every marker, map, window and document
  • set map to null on any markers
  • delete this.map on the component then set it to null
  • delete this.markers then set it to empty array

The issue i'm having at this point is that when I trigger resize, it's not resizing. after reading several other posts, and making sure i'm triggering after the div is shown, it doesn't resize. However, I have a resize function bound to window.onresize, and have noticed that after resizing the window, and the second time the function is called, the map does resize and center. here's that function:

sizeMapToContainer: function () {

    google.maps.event.trigger(this.map, 'resize');

    if (this.props.fitBounds) {
      this.zoomInOnMarkers();
    } else {
      this.map.setCenter(new google.maps.LatLng(this.props.center[1],      this.props.center[0]));
      this.map.setZoom(this.props.zoom);
    }

 },

and the function for window resize:

window.onresize = function onResize () {
  if (this.map) {
    this.sizeMapToContainer();
  }
}.bind(this);

My render call for react just returns a div, where later on in did mount I append the map div myself.

buildMap: function (nextProps) {

  var mapProps;

  if (nextProps) {
    mapProps = nextProps;
  } else {
    mapProps = this.props;
  }

  var centerpoint = mapProps.center;
  var zoom = mapProps.zoom || 8;
  var center = new google.maps.LatLng(centerpoint[1], centerpoint[0]);
  var mapNode = this.refs.map.getDOMNode();
  var mapOptions = {
    center: center,
    zoom: zoom
  };

  if (mapInstance.map) {
    window.tmMap = this.map = mapInstance.map;
    //check if the nodes are already there
    if (!mapNode.hasChildNodes()) {
      mapNode.appendChild(mapInstance.node);
    }
    this.map.setOptions(mapOptions);
  } else {
    mapInstance.node = document.createElement('div');
    mapInstance.node.classList.add('full-height');
    mapInstance.map = new google.maps.Map(mapInstance.node, mapOptions);
    window.tmMap = this.map = mapInstance.map;
    mapNode.appendChild(mapInstance.node);
    this.map.setOptions(mapOptions);
  }

  this.buildMarkers();

  this.setMarkers();

  this.bindMarkers();

  google.maps.event.addListener(this.map, 'idle', this.onIdle);

},

This component is a nested component.

Please let me know if there is any other code that will help. I am of course using the latest google maps api, using it directly.

Community
  • 1
  • 1
Kelly Milligan
  • 578
  • 1
  • 4
  • 17
  • 1
    Are you only calling `google.maps.event.trigger(this.map, 'resize')` on window resize? Don't you need to make this call each time the div resizes, rather than waiting for the window to resize? – blahman Jun 24 '15 at 00:20

0 Answers0