Skip to content

Commit

Permalink
Fix onStartReached not called when list content is small (#42902)
Browse files Browse the repository at this point in the history
Summary:
Currently if the virtualized list content is small `onStartReached` won't be called initially when the list is mounted. This is because when the content is small `onEndReached` will be called initially preventing `onStartReached` from being called. In `_maybeCallOnEdgeReached` calling `onEndReached` and `onStartReached` are in the same conditional so they cannot both be triggered at once. To improve the consistency of `onStartReached` we should call both `onEndReached` and `onStartReached` if needed.

## Changelog:

[GENERAL] [FIXED] - Call onStartReached initially when list is small and `onEndReached` is called

Pull Request resolved: #42902

Test Plan:
I used this code to test in RN Tester (replace content of RNTesterAppShared.js)

```ts
import React, { useState, useEffect } from "react";
import { StyleSheet, FlatList, View, Text, TouchableOpacity } from "react-native";

function App() {
  const [data, setData] = useState(generatePosts(4));
  const [idCount, setIdCount] = useState(1);

  const renderItem = ({ item }) => <Item data={item} />;
  const keyExtractor = (item) => item.id.toString();

  console.log("-------")
  return (
    <View style={{ flex: 1, marginVertical: 20 }}>
      <FlatList
        key={idCount}
        data={data}
        renderItem={renderItem}
        keyExtractor={keyExtractor}
        onEndReachedThreshold={0.05}
        onEndReached={() => console.log("onEndReached")}
        onStartReachedThreshold={0.05}
        onStartReached={() => console.log("onStartReached")}
        inverted
      />
      <TouchableOpacity  style={{height: 50, width: '100%', backgroundColor: 'purple'}} onPress={()=>{
          setIdCount(state => state + 1)
          setData(generatePosts(2))
      }}><Text> Press</Text></TouchableOpacity>
    </View>
  );
}

function Item({ data }) {
  return (
    <View style={styles.item}>
      <Text style={styles.title}>
        {data.id} - {data.title}
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 24,
  },
});

const generatePosts = (count, start = 0) => {
  return Array.from({ length: count }, (_, i) => ({
    title: `Title ${start + i + 1}`,
    vote: 10,
    id: start + i,
  }));
};

export default App;
```

Before the change only onEndReached is called, after the change both onStartReached and onEndReached is called.

Reviewed By: sammy-SC

Differential Revision: D53518434

Pulled By: cipolleschi

fbshipit-source-id: bc34e0d4758df6d5833be7290e5a66efaf252ffd
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Feb 8, 2024
1 parent e37da1e commit 4dcc1d3
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions packages/virtualized-lists/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
// Next check if the user just scrolled within the start threshold
// and call onStartReached only once for a given content length,
// and only if onEndReached is not being executed
else if (
if (
onStartReached != null &&
this.state.cellsAroundViewport.first === 0 &&
isWithinStartThreshold &&
Expand All @@ -1560,13 +1560,11 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {

// If the user scrolls away from the start or end and back again,
// cause onStartReached or onEndReached to be triggered again
else {
this._sentStartForContentLength = isWithinStartThreshold
? this._sentStartForContentLength
: 0;
this._sentEndForContentLength = isWithinEndThreshold
? this._sentEndForContentLength
: 0;
if (!isWithinStartThreshold) {
this._sentStartForContentLength = 0;
}
if (!isWithinEndThreshold) {
this._sentEndForContentLength = 0;
}
}

Expand Down

0 comments on commit 4dcc1d3

Please sign in to comment.