Skip to content

Commit

Permalink
invariants around scrollToIndex without getItemLayout
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sahrens authored and facebook-github-bot committed Mar 22, 2017
1 parent 462352e commit edd5624
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions Libraries/CustomComponents/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,

This comment has been minimized.

Copy link
@cbjs

cbjs May 9, 2017

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,
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit edd5624

Please sign in to comment.