Use shallowEqual and isEmpty as much as possible (#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
This commit is contained in:
Michael Diego 2018-03-13 16:59:11 -07:00 committed by GitHub
parent 8cb6939e6c
commit 486bccfc61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 35 deletions

View File

@ -2,10 +2,7 @@
.*/coverage/.*
.*/scripts/.*
.*/node_modules/flow-bin/.*
# .*/node_modules/fbjs/.*
.*/node_modules/fbjs/lib/Deferred.js.flow
.*/node_modules/.*/flow-bin.*/.*
.*/node_modules/.*/fbjs.*/.*
.*/node_modules/.*/broken.json
.*/node_modules/fixed-data-table/*
.*/node_modules/.*/fixtures/package.json

View File

@ -48,7 +48,6 @@
"dependencies": {
"@mapbox/point-geometry": "^0.1.0",
"eventemitter3": "^1.1.0",
"fbjs": "^0.8.3",
"scriptjs": "^2.5.7"
},
"devDependencies": {

View File

@ -3,9 +3,6 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
// libs
import shallowEqual from 'fbjs/lib/shallowEqual';
// helpers
import GoogleMapMap from './google_map_map';
import MarkerDispatcher from './marker_dispatcher';
@ -22,8 +19,10 @@ import raf from './utils/raf';
import pick from './utils/pick';
import omit from './utils/omit';
import log2 from './utils/math/log2';
import isEmpty from './utils/isEmpty';
import isNumber from './utils/isNumber';
import detectBrowser from './utils/detect';
import shallowEqual from './utils/shallowEqual';
import isPlainObject from './utils/isPlainObject';
import isArraysEqualEps from './utils/isArraysEqualEps';
import detectElementResize from './utils/detectElementResize';
@ -209,18 +208,13 @@ export default class GoogleMap extends Component {
);
}
if (
this.props.center === undefined &&
this.props.defaultCenter === undefined
) {
if (isEmpty(this.props.center) && isEmpty(this.props.defaultCenter)) {
console.warn(
'GoogleMap: center or defaultCenter property must be defined' // eslint-disable-line no-console
);
}
if (
this.props.zoom === undefined && this.props.defaultZoom === undefined
) {
if (isEmpty(this.props.zoom) && isEmpty(this.props.defaultZoom)) {
console.warn(
'GoogleMap: zoom or defaultZoom property must be defined' // eslint-disable-line no-console
);
@ -288,17 +282,15 @@ export default class GoogleMap extends Component {
componentWillReceiveProps(nextProps) {
if (process.env.NODE_ENV !== 'production') {
if (this.props.defaultCenter !== nextProps.defaultCenter) {
if (!shallowEqual(this.props.defaultCenter, nextProps.defaultCenter)) {
console.warn(
'GoogleMap: defaultCenter prop changed. ' + // eslint-disable-line
"You can't change default props."
"GoogleMap: defaultCenter prop changed. You can't change default props."
);
}
if (this.props.defaultZoom !== nextProps.defaultZoom) {
if (!shallowEqual(this.props.defaultZoom, nextProps.defaultZoom)) {
console.warn(
'GoogleMap: defaultZoom prop changed. ' + // eslint-disable-line
"You can't change default props."
"GoogleMap: defaultZoom prop changed. You can't change default props."
);
}
}
@ -337,26 +329,24 @@ export default class GoogleMap extends Component {
}
}
if (nextProps.zoom !== undefined) {
if (!isEmpty(nextProps.zoom)) {
// if zoom chaged by user
if (Math.abs(nextProps.zoom - this.props.zoom) > 0) {
this.map_.setZoom(nextProps.zoom);
}
}
if (
this.props.draggable !== undefined && nextProps.draggable === undefined
) {
if (!isEmpty(this.props.draggable) && isEmpty(nextProps.draggable)) {
// reset to default
this.map_.setOptions({ draggable: this.defaultDraggableOption_ });
} else if (this.props.draggable !== nextProps.draggable) {
} else if (!shallowEqual(this.props.draggable, nextProps.draggable)) {
// also prevent this on window 'mousedown' event to prevent map move
this.map_.setOptions({ draggable: nextProps.draggable });
}
// use shallowEqual to try avoid calling map._setOptions if only the ref changes
if (
nextProps.options !== undefined &&
!isEmpty(nextProps.options) &&
!shallowEqual(this.props.options, nextProps.options)
) {
const mapPlainObjects = pick(this.maps_, isPlainObject);
@ -374,7 +364,7 @@ export default class GoogleMap extends Component {
this.map_.setOptions(options);
}
if (nextProps.layerTypes !== this.props.layerTypes) {
if (!shallowEqual(nextProps.layerTypes, this.props.layerTypes)) {
Object.keys(this.layers_).forEach(layerKey => {
this.layers_[layerKey].setMap(null);
delete this.layers_[layerKey];
@ -395,7 +385,7 @@ export default class GoogleMap extends Component {
componentDidUpdate(prevProps) {
this.markersDispatcher_.emit('kON_CHANGE');
if (this.props.hoverDistance !== prevProps.hoverDistance) {
if (!shallowEqual(this.props.hoverDistance, prevProps.hoverDistance)) {
this.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
}
}
@ -453,7 +443,7 @@ export default class GoogleMap extends Component {
};
_computeMinZoom = minZoom => {
if (minZoom !== undefined && minZoom !== null) {
if (!isEmpty(minZoom)) {
return minZoom;
}
return this._getMinZoom();
@ -541,7 +531,7 @@ export default class GoogleMap extends Component {
: this.props.options;
const defaultOptions = defaultOptions_(mapPlainObjects);
const draggableOptions = this.props.draggable !== undefined && {
const draggableOptions = !isEmpty(this.props.draggable) && {
draggable: this.props.draggable,
};
@ -555,7 +545,7 @@ export default class GoogleMap extends Component {
...propsOptions,
};
this.defaultDraggableOption_ = preMapOptions.draggable !== undefined
this.defaultDraggableOption_ = !isEmpty(preMapOptions.draggable)
? preMapOptions.draggable
: this.defaultDraggableOption_;

View File

@ -1,9 +1,9 @@
/* eslint-disable react/forbid-prop-types */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import shallowEqual from 'fbjs/lib/shallowEqual';
// utils
import omit from './utils/omit';
import shallowEqual from './utils/shallowEqual';
const mainStyle = {
width: '100%',
@ -25,6 +25,7 @@ const style = {
};
export default class GoogleMapMarkers extends Component {
/* eslint-disable react/forbid-prop-types */
static propTypes = {
geoService: PropTypes.any,
style: PropTypes.any,
@ -38,6 +39,7 @@ export default class GoogleMapMarkers extends Component {
projectFromLeftTop: PropTypes.bool,
prerender: PropTypes.bool,
};
/* eslint-enable react/forbid-prop-types */
static defaultProps = {
projectFromLeftTop: false,

71
src/utils/shallowEqual.js Normal file
View File

@ -0,0 +1,71 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule shallowEqual
* @typechecks
* @flow
*/
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x: mixed, y: mixed): boolean {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
// Added the nonzero y check to make Flow happy, but it is redundant
return x !== 0 || y !== 0 || 1 / x === 1 / y;
}
// Step 6.a: NaN == NaN
// eslint-disable-next-line no-self-compare
return x !== x && y !== y;
}
/**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA: mixed, objB: mixed): boolean {
if (is(objA, objB)) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}
return true;
}
module.exports = shallowEqual;
/* src: https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/shallowEqual.js */

View File

@ -2277,7 +2277,7 @@ fastparse@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.3, fbjs@^0.8.9:
fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.9:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies: