Skip to content

Commit 2848d9d

Browse files
committed
Reduce number of setState calls dramatically
1 parent 35fd39b commit 2848d9d

2 files changed

Lines changed: 25 additions & 34 deletions

File tree

react-list.es6

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@ import ReactDOM from 'react-dom';
44

55
const {findDOMNode} = ReactDOM;
66

7-
const isEqualSubset = (a, b) => {
8-
for (let key in a) if (a[key] !== b[key]) return false;
9-
return true;
10-
};
11-
12-
const isEqual = (a, b) => isEqualSubset(a, b) && isEqualSubset(b, a);
13-
147
const CLIENT_SIZE_KEYS = {x: 'clientWidth', y: 'clientHeight'};
158
const CLIENT_START_KEYS = {x: 'clientTop', y: 'clientLeft'};
169
const INNER_SIZE_KEYS = {x: 'innerWidth', y: 'innerHeight'};
@@ -83,7 +76,7 @@ module.exports = class ReactList extends Component {
8376

8477
componentWillReceiveProps(next) {
8578
let {from, size, itemsPerRow} = this.state;
86-
this.setState(this.constrain(from, size, itemsPerRow, next));
79+
this.maybeSetState(this.constrain(from, size, itemsPerRow, next), NOOP);
8780
}
8881

8982
componentDidMount() {
@@ -92,14 +85,17 @@ module.exports = class ReactList extends Component {
9285
this.updateFrame(this.scrollTo.bind(this, this.props.initialIndex));
9386
}
9487

95-
shouldComponentUpdate(props, state) {
96-
return !isEqual(props, this.props) || !isEqual(state, this.state);
97-
}
98-
9988
componentDidUpdate() {
10089
this.updateFrame();
10190
}
10291

92+
maybeSetState(b, cb) {
93+
const a = this.state;
94+
for (let key in b) if (a[key] !== b[key]) return this.setState(b, cb);
95+
96+
cb();
97+
}
98+
10399
componentWillUnmount() {
104100
window.removeEventListener('resize', this.updateFrame);
105101
this.scrollParent.removeEventListener('scroll', this.updateFrame, PASSIVE);
@@ -257,7 +253,8 @@ module.exports = class ReactList extends Component {
257253
if (elEnd > end) return cb();
258254

259255
const {pageSize, length} = this.props;
260-
this.setState({size: Math.min(this.state.size + pageSize, length)}, cb);
256+
const size = Math.min(this.state.size + pageSize, length);
257+
this.maybeSetState({size}, cb);
261258
}
262259

263260
updateVariableFrame(cb) {
@@ -289,7 +286,7 @@ module.exports = class ReactList extends Component {
289286
++size;
290287
}
291288

292-
this.setState({from, size}, cb);
289+
this.maybeSetState({from, size}, cb);
293290
}
294291

295292
updateUniformFrame(cb) {
@@ -306,7 +303,7 @@ module.exports = class ReactList extends Component {
306303
this.props
307304
);
308305

309-
return this.setState({itemsPerRow, from, itemSize, size}, cb);
306+
return this.maybeSetState({itemsPerRow, from, itemSize, size}, cb);
310307
}
311308

312309
getSpaceBefore(index, cache = {}) {

react-list.js

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,6 @@
7878
var findDOMNode = _reactDom2.default.findDOMNode;
7979

8080

81-
var isEqualSubset = function isEqualSubset(a, b) {
82-
for (var key in a) {
83-
if (a[key] !== b[key]) return false;
84-
}return true;
85-
};
86-
87-
var isEqual = function isEqual(a, b) {
88-
return isEqualSubset(a, b) && isEqualSubset(b, a);
89-
};
90-
9181
var CLIENT_SIZE_KEYS = { x: 'clientWidth', y: 'clientHeight' };
9282
var CLIENT_START_KEYS = { x: 'clientTop', y: 'clientLeft' };
9383
var INNER_SIZE_KEYS = { x: 'innerWidth', y: 'innerHeight' };
@@ -149,7 +139,7 @@
149139
var size = _state.size;
150140
var itemsPerRow = _state.itemsPerRow;
151141

152-
this.setState(this.constrain(from, size, itemsPerRow, next));
142+
this.maybeSetState(this.constrain(from, size, itemsPerRow, next), NOOP);
153143
}
154144
}, {
155145
key: 'componentDidMount',
@@ -158,16 +148,19 @@
158148
window.addEventListener('resize', this.updateFrame);
159149
this.updateFrame(this.scrollTo.bind(this, this.props.initialIndex));
160150
}
161-
}, {
162-
key: 'shouldComponentUpdate',
163-
value: function shouldComponentUpdate(props, state) {
164-
return !isEqual(props, this.props) || !isEqual(state, this.state);
165-
}
166151
}, {
167152
key: 'componentDidUpdate',
168153
value: function componentDidUpdate() {
169154
this.updateFrame();
170155
}
156+
}, {
157+
key: 'maybeSetState',
158+
value: function maybeSetState(b, cb) {
159+
var a = this.state;
160+
for (var key in b) {
161+
if (a[key] !== b[key]) return this.setState(b, cb);
162+
}cb();
163+
}
171164
}, {
172165
key: 'componentWillUnmount',
173166
value: function componentWillUnmount() {
@@ -362,7 +355,8 @@
362355
var pageSize = _props4.pageSize;
363356
var length = _props4.length;
364357

365-
this.setState({ size: Math.min(this.state.size + pageSize, length) }, cb);
358+
var size = Math.min(this.state.size + pageSize, length);
359+
this.maybeSetState({ size: size }, cb);
366360
}
367361
}, {
368362
key: 'updateVariableFrame',
@@ -401,7 +395,7 @@
401395
++size;
402396
}
403397

404-
this.setState({ from: from, size: size }, cb);
398+
this.maybeSetState({ from: from, size: size }, cb);
405399
}
406400
}, {
407401
key: 'updateUniformFrame',
@@ -425,7 +419,7 @@
425419
var size = _constrain.size;
426420

427421

428-
return this.setState({ itemsPerRow: itemsPerRow, from: from, itemSize: itemSize, size: size }, cb);
422+
return this.maybeSetState({ itemsPerRow: itemsPerRow, from: from, itemSize: itemSize, size: size }, cb);
429423
}
430424
}, {
431425
key: 'getSpaceBefore',

0 commit comments

Comments
 (0)