-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplifies shouldComponentUpdate (open discussion) #78
Changes from 1 commit
fec0172
b38f53a
7eee6dd
61c9641
e29bdef
fe78199
77cf4e3
6a83813
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,36 +67,22 @@ function factory (methods) { | |
return shouldComponentUpdate; | ||
|
||
function shouldComponentUpdate (nextProps, nextState) { | ||
var isNotIgnorable = not(or(isStatics, isChildren)); | ||
|
||
var nextCursors = filter(nextProps, isNotIgnorable), | ||
currentCursors = filter(this.props, isNotIgnorable); | ||
|
||
var nextCursorsKeys = Object.keys(nextCursors), | ||
currentCursorsKeys = Object.keys(currentCursors); | ||
|
||
if (currentCursorsKeys.length !== nextCursorsKeys.length) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (number of cursors differ)'); | ||
return true; | ||
if (nextProps === this.props) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => false (equal input)'); | ||
return false; | ||
} | ||
|
||
if (hasDifferentKeys(currentCursorsKeys, currentCursors, nextCursors)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have different keys)'); | ||
return true; | ||
} | ||
|
||
if (hasChangedCursors(currentCursors, nextCursors)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have changed)'); | ||
return true; | ||
} | ||
var isNotIgnorable = not(or(isStatics, isChildren)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this outside of |
||
var nextProps = filter(nextProps, isNotIgnorable), | ||
currentProps = filter(this.props, isNotIgnorable); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this below var nextProps = filter(nextProps, isNotIgnorable),
currentProps = filter(this.props, isNotIgnorable); Reasoning is that it could be a pointless computation if |
||
|
||
if (!_isEqualState(this.state, nextState)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (state has changed)'); | ||
return true; | ||
} | ||
|
||
if (hasChangedProperties(currentCursors, nextCursors)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (properties have changed)'); | ||
if (!_isEqualProps(currentProps, nextProps)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (props have changed)'); | ||
return true; | ||
} | ||
|
||
|
@@ -105,33 +91,6 @@ function factory (methods) { | |
return false; | ||
} | ||
|
||
function hasChangedCursors (current, next) { | ||
current = filter(current, _isCursor); | ||
next = filter(next, _isCursor); | ||
|
||
var nextKeys = Object.keys(current), | ||
currentKeys = Object.keys(next); | ||
|
||
var nextLength = nextKeys.length; | ||
|
||
if (nextLength !== currentKeys.length) { | ||
return true; | ||
} | ||
|
||
for (var i = 0; i < nextLength; i++) { | ||
if (!_isEqualCursor(current[nextKeys[i]], next[currentKeys[i]])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
function hasChangedProperties (current, next) { | ||
current = filter(current, not(_isCursor)); | ||
next = filter(next, not(_isCursor)); | ||
return !_isEqualProps(current, next); | ||
} | ||
|
||
/** | ||
* Predicate to check if state is equal. Checks in the tree for immutable structures | ||
* and if it is, check by reference. Does not support cursors. | ||
|
@@ -147,10 +106,17 @@ function factory (methods) { | |
*/ | ||
function isEqualState (value, other) { | ||
return isEqual(value, other, function (current, next) { | ||
if (_isImmutable(current) && _isImmutable(next)) { | ||
if (current == next) { | ||
return true; | ||
} | ||
|
||
var isCurrentImmutable = _isImmutable(current); | ||
var isNextImmutable = _isImmutable(next); | ||
|
||
if (isCurrentImmutable && isNextImmutable) { | ||
return current === next; | ||
} | ||
if (_isImmutable(current) || _isImmutable(next)) { | ||
if (isCurrentImmutable || isCurrentImmutable) { | ||
return false; | ||
} | ||
return void 0; | ||
|
@@ -172,18 +138,30 @@ function factory (methods) { | |
*/ | ||
function isEqualProps (value, other) { | ||
return isEqual(value, other, function (current, next) { | ||
if (_isCursor(current) && _isCursor(next)) { | ||
if (current == next) { | ||
return true; | ||
} | ||
|
||
var isCurrentCursor = _isCursor(current); | ||
var isNextCursor = _isCursor(next); | ||
|
||
if (isCurrentCursor && isNextCursor) { | ||
return _isEqualCursor(current, next); | ||
} | ||
if (_isCursor(current) || _isCursor(next)) { | ||
if (isCurrentCursor || isNextCursor) { | ||
return false; | ||
} | ||
if (_isImmutable(current) && _isImmutable(next)) { | ||
|
||
var isCurrentImmutable = _isImmutable(current); | ||
var isNextImmutable = _isImmutable(next); | ||
|
||
if (isCurrentImmutable && isNextImmutable) { | ||
return current === next; | ||
} | ||
if (_isImmutable(current) || _isImmutable(next)) { | ||
if (isCurrentImmutable || isCurrentImmutable) { | ||
return false; | ||
} | ||
|
||
return void 0; | ||
}); | ||
} | ||
|
@@ -236,7 +214,6 @@ function factory (methods) { | |
} | ||
} | ||
|
||
|
||
/** | ||
* Predicate to check if a potential is an immutable structure or not. | ||
* Override through `shouldComponentUpdate.withDefaults` to support different cursor | ||
|
@@ -245,7 +222,7 @@ function factory (methods) { | |
* @param {maybeImmutable} value to check if it is immutable. | ||
* | ||
* @module shouldComponentUpdate.isImmutable | ||
* @returns {Object|Number|String|Boolean} | ||
* @returns {Boolean} | ||
* @api public | ||
*/ | ||
var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; | ||
|
@@ -269,7 +246,6 @@ function unCursor(cursor) { | |
return cursor.deref(); | ||
} | ||
|
||
|
||
/** | ||
* Predicate to check if `potential` is Immutable cursor or not (defaults to duck testing | ||
* Immutable.js cursors). Can override through `.withDefaults()`. | ||
|
@@ -281,13 +257,7 @@ function unCursor(cursor) { | |
* @api public | ||
*/ | ||
function isCursor (potential) { | ||
return potential && typeof potential.deref === 'function'; | ||
} | ||
|
||
function hasDifferentKeys (currentCursorsKeys, currentCursors, nextCursors) { | ||
return !currentCursorsKeys.every(function existsInBoth (key) { | ||
return typeof currentCursors[key] !== 'undefined' && typeof nextCursors[key] !== 'undefined'; | ||
}); | ||
return !!(potential && typeof potential.deref === 'function'); | ||
} | ||
|
||
function not (fn) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if
assert(nextProps === this.props && nextState !== this.state)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right.