Skip to content

Commit

Permalink
implement shallowEqual
Browse files Browse the repository at this point in the history
  • Loading branch information
rinick committed Mar 5, 2019
1 parent 21e190d commit e59e7a2
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
36 changes: 36 additions & 0 deletions src/common/util/Compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,39 @@ export function deepEqual(a: any, b: any) {
return false;
}

export function shallowEqual(a: any, b: any) {
if (Object.is(a, b)) {
return true;
}

if (a && b && typeof a === 'object' && typeof b === 'object') {
let arrA = isArray(a);
let arrB = isArray(b);

if (arrA && arrB) {
let length = a.length;
if (length !== b.length) return false;
for (let i = length; i-- !== 0;) {
if (!Object.is(a[i], b[i])) return false;
}
return true;
}

if (arrA !== arrB) return false;

let keys = keyList(a);

if (keys.length !== keyList(b).length) {
return false;
}

for (let key of keys) {
if (!Object.is(a[key], b[key])) {
return false;
}
}

return true;
}
return false;
}
27 changes: 25 additions & 2 deletions src/common/util/spec/Compare.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {assert} from "chai";
import {arrayEqual, deepEqual} from '../Compare';
import {arrayEqual, deepEqual, shallowEqual} from '../Compare';

describe("Compare", function () {

Expand All @@ -19,6 +19,8 @@ describe("Compare", function () {
assert.isTrue(deepEqual([1, 'a'], [1, 'a']));
assert.isTrue(deepEqual({a: 1}, {a: 1}));

assert.isTrue(deepEqual({a: {aa: 1}, b: [2]}, {a: {aa: 1}, b: [2]}));

assert.isFalse(deepEqual('a', 1));
assert.isFalse(deepEqual(null, undefined));
assert.isFalse(deepEqual([], {}));
Expand All @@ -28,4 +30,25 @@ describe("Compare", function () {
assert.isFalse(deepEqual({a: 1, b: 1}, {a: 1}));
assert.isFalse(deepEqual({a: 1}, {a: 1, b: undefined}));
});
});

it('shallowEqual', function () {
assert.isTrue(shallowEqual(1, 1));
assert.isTrue(shallowEqual(NaN, NaN));
assert.isTrue(shallowEqual(undefined, undefined));
assert.isTrue(shallowEqual('a', 'a'));
assert.isTrue(shallowEqual(true, true));
assert.isTrue(shallowEqual([1, 'a'], [1, 'a']));
assert.isTrue(shallowEqual({a: 1}, {a: 1}));

assert.isFalse(shallowEqual({a: {aa: 1}, b: [2]}, {a: {aa: 1}, b: [2]}));

assert.isFalse(shallowEqual('a', 1));
assert.isFalse(shallowEqual(null, undefined));
assert.isFalse(shallowEqual([], {}));
assert.isFalse(shallowEqual([1], [1, 1]));
assert.isFalse(shallowEqual([1], [2]));
assert.isFalse(shallowEqual({a: 1}, {a: 2}));
assert.isFalse(shallowEqual({a: 1, b: 1}, {a: 1}));
assert.isFalse(shallowEqual({a: 1}, {a: 1, b: undefined}));
});
});
5 changes: 5 additions & 0 deletions src/ui/component/LazyUpdateComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import {ClientConnection, ValueUpdate} from "../../common";
import {DataMap} from "../../common/util/Types";
import {shallowEqual} from "../../common/util/Compare";

interface LazyUpdateProps {
conn: ClientConnection;
Expand All @@ -18,6 +19,10 @@ export abstract class LazyUpdateComponent<P extends LazyUpdateProps, S> extends
return result;
}

shouldComponentUpdate(nextProps: Readonly<P>, nextState: Readonly<S>): boolean {
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
}

abstract renderImpl(): React.ReactNode;

forceUpdate() {
Expand Down

0 comments on commit e59e7a2

Please sign in to comment.