Skip to content

Commit

Permalink
perf(src): switch mapHolderRef from props to context
Browse files Browse the repository at this point in the history
* Improved performance of rendering many markers/components on the map
* Closes #135
* Closes #210
* Closes #216

BREAKING CHANGE: If you're just using the library and didn't make custom components before, feel free to ignore this implementation changes.

Now, mapHolderRef for each component are now passed in via context. This doesn't affect all components interface in general. But if you do custom components before and relies on the implementation of react-google-maps, you should be aware of this and make some changes.
  • Loading branch information
rewop authored and tomchentw committed May 30, 2016
1 parent 472e29c commit c2d265c
Show file tree
Hide file tree
Showing 26 changed files with 174 additions and 61 deletions.
14 changes: 13 additions & 1 deletion src/Circle.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
circleEventPropTypes,
} from "./creators/CircleCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

export default class Circle extends Component {
static propTypes = {
// Uncontrolled default[props] - used only in componentDidMount
Expand All @@ -24,6 +27,10 @@ export default class Circle extends Component {
...circleEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#Circle
Expand All @@ -50,10 +57,15 @@ export default class Circle extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const circle = CircleCreator._createCircle(this.props);
const circle = CircleCreator._createCircle({
...this.props,
mapHolderRef,
});

this.setState({ circle });
}
Expand Down
14 changes: 13 additions & 1 deletion src/DirectionsRenderer.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
directionsRendererEventPropTypes,
} from "./creators/DirectionsRendererCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

/*
* Original author: @alexishevia
* Original PR: https://github.com/tomchentw/react-google-maps/pull/22
Expand All @@ -28,6 +31,10 @@ export default class DirectionsRenderer extends Component {
...directionsRendererEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsRenderer
Expand All @@ -46,10 +53,15 @@ export default class DirectionsRenderer extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const directionsRenderer = DirectionsRendererCreator._createDirectionsRenderer(this.props);
const directionsRenderer = DirectionsRendererCreator._createDirectionsRenderer({
...this.props,
mapHolderRef,
});

this.setState({ directionsRenderer });
}
Expand Down
14 changes: 13 additions & 1 deletion src/DrawingManager.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
drawingManagerEventPropTypes,
} from "./creators/DrawingManagerCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

/*
* Original author: @idolize
* Original PR: https://github.com/tomchentw/react-google-maps/pull/46
Expand All @@ -28,6 +31,10 @@ export default class DrawingManager extends Component {
...drawingManagerEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#DrawingManager
Expand All @@ -42,10 +49,15 @@ export default class DrawingManager extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const drawingManager = DrawingManagerCreator._createDrawingManager(this.props);
const drawingManager = DrawingManagerCreator._createDrawingManager({
...this.props,
mapHolderRef,
});

this.setState({ drawingManager });
}
Expand Down
14 changes: 13 additions & 1 deletion src/InfoWindow.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
infoWindowEventPropTypes,
} from "./creators/InfoWindowCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

export default class InfoWindow extends Component {
static propTypes = {
// Uncontrolled default[props] - used only in componentDidMount
Expand All @@ -24,6 +27,10 @@ export default class InfoWindow extends Component {
...infoWindowEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#InfoWindow
Expand All @@ -42,10 +49,15 @@ export default class InfoWindow extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const infoWindow = InfoWindowCreator._createInfoWindow(this.props);
const infoWindow = InfoWindowCreator._createInfoWindow({
...this.props,
mapHolderRef,
});

this.setState({ infoWindow });
}
Expand Down
17 changes: 15 additions & 2 deletions src/KmlLayer.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
kmlLayerEventPropTypes,
} from "./creators/KmlLayerCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

export default class KmlLayer extends Component {
static propTypes = {
// Uncontrolled default[props] - used only in componentDidMount
Expand All @@ -24,6 +27,10 @@ export default class KmlLayer extends Component {
...kmlLayerEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#KmlLayer
Expand All @@ -46,18 +53,24 @@ export default class KmlLayer extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const kmlLayer = KmlLayerCreator._createKmlLayer(this.props);
const kmlLayer = KmlLayerCreator._createKmlLayer({
...this.props,
mapHolderRef,
});

this.setState({ kmlLayer });
}

render() {
const { mapHolderRef } = this.context;
if (this.state.kmlLayer) {
return (
<KmlLayerCreator kmlLayer={this.state.kmlLayer} {...this.props}>
<KmlLayerCreator mapHolderRef={mapHolderRef} kmlLayer={this.state.kmlLayer} {...this.props}>
{this.props.children}
</KmlLayerCreator>
);
Expand Down
13 changes: 12 additions & 1 deletion src/Marker.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
markerEventPropTypes,
} from "./creators/MarkerCreator";

import GoogleMapHolder from "./creators/GoogleMapHolder";

export default class Marker extends Component {
static propTypes = {
// Uncontrolled default[props] - used only in componentDidMount
Expand All @@ -24,6 +27,10 @@ export default class Marker extends Component {
...markerEventPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#Marker
Expand Down Expand Up @@ -64,10 +71,14 @@ export default class Marker extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;
if (!canUseDOM) {
return;
}
const marker = MarkerCreator._createMarker(this.props);
const marker = MarkerCreator._createMarker({
...this.props,
mapHolderRef,
});

this.setState({ marker });
}
Expand Down
10 changes: 9 additions & 1 deletion src/OverlayView.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -13,6 +14,8 @@ import {
overlayViewControlledPropTypes,
} from "./creators/OverlayViewCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

/*
* Original author: @petebrowne
* Original PR: https://github.com/tomchentw/react-google-maps/pull/63
Expand All @@ -32,6 +35,10 @@ export default class OverlayView extends Component {
...overlayViewControlledPropTypes,
}

static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

static defaultProps = {
mapPaneName: OverlayView.OVERLAY_LAYER,
}
Expand Down Expand Up @@ -61,9 +68,10 @@ export default class OverlayView extends Component {
}

render() {
const { mapHolderRef } = this.context;
if (this.state.overlayView) {
return (
<OverlayViewCreator overlayView={this.state.overlayView} {...this.props}>
<OverlayViewCreator mapHolderRef={mapHolderRef} overlayView={this.state.overlayView} {...this.props}>
{this.props.children}
</OverlayViewCreator>
);
Expand Down
13 changes: 12 additions & 1 deletion src/Polygon.js
@@ -1,6 +1,7 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
Expand All @@ -14,6 +15,8 @@ import {
polygonEventPropTypes,
} from "./creators/PolygonCreator";

import { default as GoogleMapHolder } from "./creators/GoogleMapHolder";

export default class Polygon extends Component {
static propTypes = {
// Uncontrolled default[props] - used only in componentDidMount
Expand All @@ -23,6 +26,9 @@ export default class Polygon extends Component {
// Event [onEventName]
...polygonEventPropTypes,
}
static contextTypes = {
mapHolderRef: PropTypes.instanceOf(GoogleMapHolder),
}

// Public APIs
//
Expand All @@ -46,10 +52,15 @@ export default class Polygon extends Component {
}

componentWillMount() {
const { mapHolderRef } = this.context;

if (!canUseDOM) {
return;
}
const polygon = PolygonCreator._createPolygon(this.props);
const polygon = PolygonCreator._createPolygon({
...this.props,
mapHolderRef,
});

this.setState({ polygon });
}
Expand Down

0 comments on commit c2d265c

Please sign in to comment.