Skip to content

Commit d528e96

Browse files
YunPeng Chongfacebook-github-bot
authored andcommitted
Fix onEndReached not being called when getItemLayout is present and we scroll past render window (#46990)
Summary: 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
1 parent 401991c commit d528e96

2 files changed

Lines changed: 26 additions & 6 deletions

File tree

‎packages/virtualized-lists/Lists/VirtualizedList.js‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
11601160
}
11611161

11621162
componentDidUpdate(prevProps: Props) {
1163-
const {data, extraData} = this.props;
1163+
const {data, extraData, getItemLayout} = this.props;
11641164
if (data !== prevProps.data || extraData !== prevProps.extraData) {
11651165
// clear the viewableIndices cache to also trigger
11661166
// the onViewableItemsChanged callback with the new data
@@ -1181,6 +1181,14 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
11811181
if (hiPriInProgress) {
11821182
this._hiPriInProgress = false;
11831183
}
1184+
1185+
// We only call `onEndReached` after we render the last cell, but when
1186+
// getItemLayout is present, we can scroll past the last rendered cell, and
1187+
// never trigger a new layout or bounds change, so we need to check again
1188+
// after rendering more cells.
1189+
if (getItemLayout != null) {
1190+
this._maybeCallOnEdgeReached();
1191+
}
11841192
}
11851193

11861194
_cellRefs: {[string]: null | CellRenderer<any>} = {};
@@ -1496,6 +1504,14 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
14961504
onEndReached,
14971505
onEndReachedThreshold,
14981506
} = this.props;
1507+
// Wait until we have real metrics
1508+
if (
1509+
!this._listMetrics.hasContentLength() ||
1510+
this._scrollMetrics.visibleLength === 0
1511+
) {
1512+
return;
1513+
}
1514+
14991515
// If we have any pending scroll updates it means that the scroll metrics
15001516
// are out of date and we should not call any of the edge reached callbacks.
15011517
if (this.state.pendingScrollUpdateCount > 0) {

‎packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,11 +663,6 @@ describe('VirtualizedList', () => {
663663
renderItem: ({item}) => <item value={item.key} />,
664664
getItem: (items, index) => items[index],
665665
getItemCount: items => items.length,
666-
getItemLayout: (items, index) => ({
667-
length: ITEM_HEIGHT,
668-
offset: ITEM_HEIGHT * index,
669-
index,
670-
}),
671666
onEndReached,
672667
};
673668

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

696691
await act(() => {
692+
for (let i = 0; i < 20; ++i) {
693+
simulateCellLayout(component, data, i, {
694+
width: 10,
695+
height: ITEM_HEIGHT,
696+
x: 0,
697+
y: i * ITEM_HEIGHT,
698+
});
699+
}
700+
697701
instance._onScroll({
698702
timeStamp: 1000,
699703
nativeEvent: {

0 commit comments

Comments
 (0)