Skip to content

Commit 486bccf

Browse files
Use shallowEqual and isEmpty as much as possible (google-map-react#540)
* Use shallowCompare to compare objects * Use isEmpty as much as possible * Use our own shallowEqual * Remove fbjs * Just disable necessary line * Add eslint-disable where needed
1 parent 8cb6939 commit 486bccf

File tree

6 files changed

+94
-35
lines changed

6 files changed

+94
-35
lines changed

Diff for: .flowconfig

-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
.*/coverage/.*
33
.*/scripts/.*
44
.*/node_modules/flow-bin/.*
5-
# .*/node_modules/fbjs/.*
6-
.*/node_modules/fbjs/lib/Deferred.js.flow
75
.*/node_modules/.*/flow-bin.*/.*
8-
.*/node_modules/.*/fbjs.*/.*
96
.*/node_modules/.*/broken.json
107
.*/node_modules/fixed-data-table/*
118
.*/node_modules/.*/fixtures/package.json

Diff for: package.json

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
"dependencies": {
4949
"@mapbox/point-geometry": "^0.1.0",
5050
"eventemitter3": "^1.1.0",
51-
"fbjs": "^0.8.3",
5251
"scriptjs": "^2.5.7"
5352
},
5453
"devDependencies": {

Diff for: src/google_map.js

+17-27
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import React, { Component } from 'react';
33
import PropTypes from 'prop-types';
44
import ReactDOM from 'react-dom';
55

6-
// libs
7-
import shallowEqual from 'fbjs/lib/shallowEqual';
8-
96
// helpers
107
import GoogleMapMap from './google_map_map';
118
import MarkerDispatcher from './marker_dispatcher';
@@ -22,8 +19,10 @@ import raf from './utils/raf';
2219
import pick from './utils/pick';
2320
import omit from './utils/omit';
2421
import log2 from './utils/math/log2';
22+
import isEmpty from './utils/isEmpty';
2523
import isNumber from './utils/isNumber';
2624
import detectBrowser from './utils/detect';
25+
import shallowEqual from './utils/shallowEqual';
2726
import isPlainObject from './utils/isPlainObject';
2827
import isArraysEqualEps from './utils/isArraysEqualEps';
2928
import detectElementResize from './utils/detectElementResize';
@@ -209,18 +208,13 @@ export default class GoogleMap extends Component {
209208
);
210209
}
211210

212-
if (
213-
this.props.center === undefined &&
214-
this.props.defaultCenter === undefined
215-
) {
211+
if (isEmpty(this.props.center) && isEmpty(this.props.defaultCenter)) {
216212
console.warn(
217213
'GoogleMap: center or defaultCenter property must be defined' // eslint-disable-line no-console
218214
);
219215
}
220216

221-
if (
222-
this.props.zoom === undefined && this.props.defaultZoom === undefined
223-
) {
217+
if (isEmpty(this.props.zoom) && isEmpty(this.props.defaultZoom)) {
224218
console.warn(
225219
'GoogleMap: zoom or defaultZoom property must be defined' // eslint-disable-line no-console
226220
);
@@ -288,17 +282,15 @@ export default class GoogleMap extends Component {
288282

289283
componentWillReceiveProps(nextProps) {
290284
if (process.env.NODE_ENV !== 'production') {
291-
if (this.props.defaultCenter !== nextProps.defaultCenter) {
285+
if (!shallowEqual(this.props.defaultCenter, nextProps.defaultCenter)) {
292286
console.warn(
293-
'GoogleMap: defaultCenter prop changed. ' + // eslint-disable-line
294-
"You can't change default props."
287+
"GoogleMap: defaultCenter prop changed. You can't change default props."
295288
);
296289
}
297290

298-
if (this.props.defaultZoom !== nextProps.defaultZoom) {
291+
if (!shallowEqual(this.props.defaultZoom, nextProps.defaultZoom)) {
299292
console.warn(
300-
'GoogleMap: defaultZoom prop changed. ' + // eslint-disable-line
301-
"You can't change default props."
293+
"GoogleMap: defaultZoom prop changed. You can't change default props."
302294
);
303295
}
304296
}
@@ -337,26 +329,24 @@ export default class GoogleMap extends Component {
337329
}
338330
}
339331

340-
if (nextProps.zoom !== undefined) {
332+
if (!isEmpty(nextProps.zoom)) {
341333
// if zoom chaged by user
342334
if (Math.abs(nextProps.zoom - this.props.zoom) > 0) {
343335
this.map_.setZoom(nextProps.zoom);
344336
}
345337
}
346338

347-
if (
348-
this.props.draggable !== undefined && nextProps.draggable === undefined
349-
) {
339+
if (!isEmpty(this.props.draggable) && isEmpty(nextProps.draggable)) {
350340
// reset to default
351341
this.map_.setOptions({ draggable: this.defaultDraggableOption_ });
352-
} else if (this.props.draggable !== nextProps.draggable) {
342+
} else if (!shallowEqual(this.props.draggable, nextProps.draggable)) {
353343
// also prevent this on window 'mousedown' event to prevent map move
354344
this.map_.setOptions({ draggable: nextProps.draggable });
355345
}
356346

357347
// use shallowEqual to try avoid calling map._setOptions if only the ref changes
358348
if (
359-
nextProps.options !== undefined &&
349+
!isEmpty(nextProps.options) &&
360350
!shallowEqual(this.props.options, nextProps.options)
361351
) {
362352
const mapPlainObjects = pick(this.maps_, isPlainObject);
@@ -374,7 +364,7 @@ export default class GoogleMap extends Component {
374364
this.map_.setOptions(options);
375365
}
376366

377-
if (nextProps.layerTypes !== this.props.layerTypes) {
367+
if (!shallowEqual(nextProps.layerTypes, this.props.layerTypes)) {
378368
Object.keys(this.layers_).forEach(layerKey => {
379369
this.layers_[layerKey].setMap(null);
380370
delete this.layers_[layerKey];
@@ -395,7 +385,7 @@ export default class GoogleMap extends Component {
395385
componentDidUpdate(prevProps) {
396386
this.markersDispatcher_.emit('kON_CHANGE');
397387

398-
if (this.props.hoverDistance !== prevProps.hoverDistance) {
388+
if (!shallowEqual(this.props.hoverDistance, prevProps.hoverDistance)) {
399389
this.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
400390
}
401391
}
@@ -453,7 +443,7 @@ export default class GoogleMap extends Component {
453443
};
454444

455445
_computeMinZoom = minZoom => {
456-
if (minZoom !== undefined && minZoom !== null) {
446+
if (!isEmpty(minZoom)) {
457447
return minZoom;
458448
}
459449
return this._getMinZoom();
@@ -541,7 +531,7 @@ export default class GoogleMap extends Component {
541531
: this.props.options;
542532
const defaultOptions = defaultOptions_(mapPlainObjects);
543533

544-
const draggableOptions = this.props.draggable !== undefined && {
534+
const draggableOptions = !isEmpty(this.props.draggable) && {
545535
draggable: this.props.draggable,
546536
};
547537

@@ -555,7 +545,7 @@ export default class GoogleMap extends Component {
555545
...propsOptions,
556546
};
557547

558-
this.defaultDraggableOption_ = preMapOptions.draggable !== undefined
548+
this.defaultDraggableOption_ = !isEmpty(preMapOptions.draggable)
559549
? preMapOptions.draggable
560550
: this.defaultDraggableOption_;
561551

Diff for: src/google_map_markers.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
/* eslint-disable react/forbid-prop-types */
2-
31
import React, { Component } from 'react';
42
import PropTypes from 'prop-types';
5-
import shallowEqual from 'fbjs/lib/shallowEqual';
3+
4+
// utils
65
import omit from './utils/omit';
6+
import shallowEqual from './utils/shallowEqual';
77

88
const mainStyle = {
99
width: '100%',
@@ -25,6 +25,7 @@ const style = {
2525
};
2626

2727
export default class GoogleMapMarkers extends Component {
28+
/* eslint-disable react/forbid-prop-types */
2829
static propTypes = {
2930
geoService: PropTypes.any,
3031
style: PropTypes.any,
@@ -38,6 +39,7 @@ export default class GoogleMapMarkers extends Component {
3839
projectFromLeftTop: PropTypes.bool,
3940
prerender: PropTypes.bool,
4041
};
42+
/* eslint-enable react/forbid-prop-types */
4143

4244
static defaultProps = {
4345
projectFromLeftTop: false,

Diff for: src/utils/shallowEqual.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @providesModule shallowEqual
8+
* @typechecks
9+
* @flow
10+
*/
11+
12+
const hasOwnProperty = Object.prototype.hasOwnProperty;
13+
14+
/**
15+
* inlined Object.is polyfill to avoid requiring consumers ship their own
16+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
17+
*/
18+
function is(x: mixed, y: mixed): boolean {
19+
// SameValue algorithm
20+
if (x === y) {
21+
// Steps 1-5, 7-10
22+
// Steps 6.b-6.e: +0 != -0
23+
// Added the nonzero y check to make Flow happy, but it is redundant
24+
return x !== 0 || y !== 0 || 1 / x === 1 / y;
25+
}
26+
// Step 6.a: NaN == NaN
27+
// eslint-disable-next-line no-self-compare
28+
return x !== x && y !== y;
29+
}
30+
31+
/**
32+
* Performs equality by iterating through keys on an object and returning false
33+
* when any key has values which are not strictly equal between the arguments.
34+
* Returns true when the values of all keys are strictly equal.
35+
*/
36+
function shallowEqual(objA: mixed, objB: mixed): boolean {
37+
if (is(objA, objB)) {
38+
return true;
39+
}
40+
41+
if (
42+
typeof objA !== 'object' ||
43+
objA === null ||
44+
typeof objB !== 'object' ||
45+
objB === null
46+
) {
47+
return false;
48+
}
49+
50+
const keysA = Object.keys(objA);
51+
const keysB = Object.keys(objB);
52+
53+
if (keysA.length !== keysB.length) {
54+
return false;
55+
}
56+
57+
// Test for A's keys different from B.
58+
for (let i = 0; i < keysA.length; i++) {
59+
if (
60+
!hasOwnProperty.call(objB, keysA[i]) ||
61+
!is(objA[keysA[i]], objB[keysA[i]])
62+
) {
63+
return false;
64+
}
65+
}
66+
67+
return true;
68+
}
69+
70+
module.exports = shallowEqual;
71+
/* src: https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/shallowEqual.js */

Diff for: yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -2277,7 +2277,7 @@ fastparse@^1.1.1:
22772277
version "1.1.1"
22782278
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
22792279

2280-
fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.3, fbjs@^0.8.9:
2280+
fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.9:
22812281
version "0.8.16"
22822282
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
22832283
dependencies:

0 commit comments

Comments
 (0)