Skip to content

Commit

Permalink
Fixing onEndReachedThreshold === 0 not firing onEndReached function o…
Browse files Browse the repository at this point in the history
…n Android.

Summary:
Changelog:
[Android][Fix] - When `onEndReachedThreshold` is set to 0 `onEndReached` function on `VirtualizedList` properly fires once the user scrolls to the bottom of the list.

Reviewed By: genkikondo

Differential Revision: D36488189

fbshipit-source-id: b95f3291f2957273280696d8840c1e000d669380
  • Loading branch information
Christian Ruink authored and facebook-github-bot committed Jun 7, 2022
1 parent 21a4c1f commit b869680
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions Libraries/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const FillRateHelper = require('./FillRateHelper');
const ViewabilityHelper = require('./ViewabilityHelper');
const invariant = require('invariant');

const ON_END_REACHED_EPSILON = 0.001;

type Item = any;

export type Separators = {
Expand Down Expand Up @@ -218,7 +220,8 @@ type OptionalProps = {|
* How far from the end (in units of visible length of the list) the bottom edge of the
* list must be from the end of the content to trigger the `onEndReached` callback.
* Thus a value of 0.5 will trigger `onEndReached` when the end of the content is
* within half the visible length of the list.
* within half the visible length of the list. A value of 0 will not trigger until scrolling
* to the very end of the list.
*/
onEndReachedThreshold?: ?number,
/**
Expand Down Expand Up @@ -1516,13 +1519,22 @@ class VirtualizedList extends React.PureComponent<Props, State> {
const {data, getItemCount, onEndReached, onEndReachedThreshold} =
this.props;
const {contentLength, visibleLength, offset} = this._scrollMetrics;
const distanceFromEnd = contentLength - visibleLength - offset;
let distanceFromEnd = contentLength - visibleLength - offset;

// Especially when oERT is zero it's necessary to 'floor' very small distanceFromEnd values to be 0
// since debouncing causes us to not fire this event for every single "pixel" we scroll and can thus
// be at the "end" of the list with a distanceFromEnd approximating 0 but not quite there.
if (distanceFromEnd < ON_END_REACHED_EPSILON) {
distanceFromEnd = 0;
}

// TODO: T121172172 Look into why we're "defaulting" to a threshold of 2 when oERT is not present
const threshold =
onEndReachedThreshold != null ? onEndReachedThreshold * visibleLength : 2;
if (
onEndReached &&
this.state.last === getItemCount(data) - 1 &&
distanceFromEnd < threshold &&
distanceFromEnd <= threshold &&
this._scrollMetrics.contentLength !== this._sentEndForContentLength
) {
// Only call onEndReached once for a given content length
Expand Down

0 comments on commit b869680

Please sign in to comment.