diff --git a/src/ObjectUtils.js b/src/ObjectUtils.js index 41dc34cca7..07a16df501 100644 --- a/src/ObjectUtils.js +++ b/src/ObjectUtils.js @@ -77,3 +77,34 @@ module.exports.getKeyValueArrayDiffs = function(before, after) { return results; }; + +/** + * Shallow-compare two objects for equality: each key and value must be + * identical + */ +module.exports.shallowEqual = function(objA, objB) { + if (objA === objB) { + return true; + } + + if (typeof objA !== 'object' || objA === null || + typeof objB !== 'object' || objB === null) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } + + for (var i = 0; i < keysA.length; i++) { + var key = keysA[i]; + if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) { + return false; + } + } + + return true; +}; diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3cd933eaaa..6304cc4f48 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -38,6 +38,7 @@ var SlashCommands = require("../../SlashCommands"); var dis = require("../../dispatcher"); var Tinter = require("../../Tinter"); var rate_limited_func = require('../../ratelimitedfunc'); +var ObjectUtils = require('../../ObjectUtils'); var DEBUG = false; @@ -164,6 +165,11 @@ module.exports = React.createClass({ } }, + shouldComponentUpdate: function(nextProps, nextState) { + return (!ObjectUtils.shallowEqual(this.props, nextProps) || + !ObjectUtils.shallowEqual(this.state, nextState)); + }, + componentWillUnmount: function() { // set a boolean to say we've been unmounted, which any pending // promises can use to throw away their results. diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index ff4df26179..04ae3fa4f1 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -24,6 +24,7 @@ var EventTimeline = Matrix.EventTimeline; var sdk = require('../../index'); var MatrixClientPeg = require("../../MatrixClientPeg"); var dis = require("../../dispatcher"); +var ObjectUtils = require('../../ObjectUtils'); var PAGINATE_SIZE = 20; var INITIAL_SIZE = 20; @@ -146,6 +147,11 @@ var TimelinePanel = React.createClass({ } }, + shouldComponentUpdate: function(nextProps, nextState) { + return (!ObjectUtils.shallowEqual(this.props, nextProps) || + !ObjectUtils.shallowEqual(this.state, nextState)); + }, + componentWillUnmount: function() { // set a boolean to say we've been unmounted, which any pending // promises can use to throw away their results.