Skip to content

Commit

Permalink
Fix onEndReached not being called when getItemLayout is present and w…
Browse files Browse the repository at this point in the history
…e scroll past render window (#46990)

Summary:
Pull Request resolved: #46990

This is a reattempt land D63643856 to fix the scroll onendreached event not firing.

Changelog:
[General][Fixed] - Fix onEndReached not being called when getItemLayout is present and we scroll past render window

Reviewed By: NickGerleman

Differential Revision: D64222424

fbshipit-source-id: 7e22f377d2f754beb39fff2b5c097cea350daa7e
  • Loading branch information
YunPeng Chong authored and facebook-github-bot committed Oct 14, 2024
1 parent 0902b0a commit 3485e9e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
18 changes: 17 additions & 1 deletion packages/virtualized-lists/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
}

componentDidUpdate(prevProps: Props) {
const {data, extraData} = this.props;
const {data, extraData, getItemLayout} = this.props;
if (data !== prevProps.data || extraData !== prevProps.extraData) {
// clear the viewableIndices cache to also trigger
// the onViewableItemsChanged callback with the new data
Expand All @@ -1181,6 +1181,14 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
if (hiPriInProgress) {
this._hiPriInProgress = false;
}

// We only call `onEndReached` after we render the last cell, but when
// getItemLayout is present, we can scroll past the last rendered cell, and
// never trigger a new layout or bounds change, so we need to check again
// after rendering more cells.
if (getItemLayout != null) {
this._maybeCallOnEdgeReached();
}
}

_cellRefs: {[string]: null | CellRenderer<any>} = {};
Expand Down Expand Up @@ -1496,6 +1504,14 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
onEndReached,
onEndReachedThreshold,
} = this.props;
// Wait until we have real metrics
if (
!this._listMetrics.hasContentLength() ||
this._scrollMetrics.visibleLength === 0
) {
return;
}

// If we have any pending scroll updates it means that the scroll metrics
// are out of date and we should not call any of the edge reached callbacks.
if (this.state.pendingScrollUpdateCount > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,11 +663,6 @@ describe('VirtualizedList', () => {
renderItem: ({item}) => <item value={item.key} />,
getItem: (items, index) => items[index],
getItemCount: items => items.length,
getItemLayout: (items, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
}),
onEndReached,
};

Expand All @@ -694,6 +689,15 @@ describe('VirtualizedList', () => {
expect(onEndReached).not.toHaveBeenCalled();

await act(() => {
for (let i = 0; i < 20; ++i) {
simulateCellLayout(component, data, i, {
width: 10,
height: ITEM_HEIGHT,
x: 0,
y: i * ITEM_HEIGHT,
});
}

instance._onScroll({
timeStamp: 1000,
nativeEvent: {
Expand Down

0 comments on commit 3485e9e

Please sign in to comment.