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
This commit is contained in:
Spencer Ahrens 2017-03-21 22:18:59 -07:00 committed by Facebook Github Bot
parent 462352e609
commit edd5624fde
1 changed files with 13 additions and 5 deletions

View File

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