From d7d4fae1013a9d881eb68d5eb9d0a0e632eab0f0 Mon Sep 17 00:00:00 2001 From: Martin Sherburn Date: Fri, 27 Mar 2020 03:54:58 -0700 Subject: [PATCH] Fix issue with onEndReached Summary: onEndReached can be triggered twice when more items are added to the end of the list. This change makes it so that a second call to onEndReached won't happen until the user scrolls down to the new end of the list. Changelog: [General] [Fixed] - Fix double call to onEndReached in VirtualizedList Reviewed By: sahrens Differential Revision: D20066740 fbshipit-source-id: 129d7ae6bfd241eeea18fe0bb12b82be67735874 --- Libraries/Lists/VirtualizedList.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 5ef712ca32f87a..42d2703e371023 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -1169,8 +1169,6 @@ class VirtualizedList extends React.PureComponent { componentDidUpdate(prevProps: Props) { const {data, extraData} = this.props; if (data !== prevProps.data || extraData !== prevProps.extraData) { - this._hasDataChangedSinceEndReached = true; - // clear the viewableIndices cache to also trigger // the onViewableItemsChanged callback with the new data this._viewabilityTuples.forEach(tuple => { @@ -1199,7 +1197,6 @@ class VirtualizedList extends React.PureComponent { _fillRateHelper: FillRateHelper; _frames = {}; _footerLength = 0; - _hasDataChangedSinceEndReached = true; _hasDoneInitialScroll = false; _hasInteracted = false; _hasMore = false; @@ -1491,20 +1488,22 @@ class VirtualizedList extends React.PureComponent { } = this.props; const {contentLength, visibleLength, offset} = this._scrollMetrics; const distanceFromEnd = contentLength - visibleLength - offset; + const threshold = onEndReachedThreshold + ? onEndReachedThreshold * visibleLength + : 0; if ( onEndReached && this.state.last === getItemCount(data) - 1 && - /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.63 was deployed. To see the error delete this - * comment and run Flow. */ - distanceFromEnd < onEndReachedThreshold * visibleLength && - (this._hasDataChangedSinceEndReached || - this._scrollMetrics.contentLength !== this._sentEndForContentLength) + distanceFromEnd < threshold && + this._scrollMetrics.contentLength !== this._sentEndForContentLength ) { - // Only call onEndReached once for a given dataset + content length. - this._hasDataChangedSinceEndReached = false; + // Only call onEndReached once for a given content length this._sentEndForContentLength = this._scrollMetrics.contentLength; onEndReached({distanceFromEnd}); + } else if (distanceFromEnd > threshold) { + // If the user scrolls away from the end and back again cause + // an onEndReached to be triggered again + this._sentEndForContentLength = 0; } }