Skip to content

Commit edd5624

Browse files
sahrensfacebook-github-bot
authored andcommitted
invariants around scrollToIndex without getItemLayout
Summary: People might be tempted to try and scrollTo an index that hasn't been rendered yet, which is broken, so instead of jank let's throw. Reviewed By: yungsters Differential Revision: D4727402 fbshipit-source-id: b6f9fd5b70b6f076c30141d00b2b9e2a51b14e87
1 parent 462352e commit edd5624

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

Libraries/CustomComponents/Lists/VirtualizedList.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,17 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
195195

196196
// scrollToIndex may be janky without getItemLayout prop
197197
scrollToIndex(params: {animated?: ?boolean, index: number, viewPosition?: number}) {
198-
const {data, horizontal, getItemCount} = this.props;
198+
const {data, horizontal, getItemCount, getItemLayout} = this.props;
199199
const {animated, index, viewPosition} = params;
200-
if (!(index >= 0 && index < getItemCount(data))) {
201-
console.warn('scrollToIndex out of range ' + index);
202-
return;
203-
}
200+
invariant(
201+
index >= 0 && index < getItemCount(data),
202+
`scrollToIndex out of range: ${index} vs ${getItemCount(data) - 1}`,
203+
);
204+
invariant(
205+
getItemLayout || index < this._highestMeasuredFrameIndex,
206+
'scrollToIndex should be used in conjunction with getItemLayout, ' +
207+
'otherwise there is no way to know the location of an arbitrary index.',
208+
);
204209
const frame = this._getFrameMetricsApprox(index);
205210
const offset = Math.max(
206211
0,
@@ -390,6 +395,9 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
390395
}
391396
if (!disableVirtualization && last < itemCount - 1) {
392397
const lastFrame = this._getFrameMetricsApprox(last);
398+
// Without getItemLayout, we limit our tail spacer to the _highestMeasuredFrameIndex to
399+
// prevent the user for hyperscrolling into un-measured area because otherwise content will
400+
// likely jump around as it renders in above the viewport.
393401
const end = this.props.getItemLayout ?
394402
itemCount - 1 :
395403
Math.min(itemCount - 1, this._highestMeasuredFrameIndex);

0 commit comments

Comments
 (0)