FlatList onEndReached Called On Load [iOS] (with detailed findings)
See original GitHub issueIs this a bug report?
Yes
Have you read the Contributing Guidelines?
Yes
Environment
Environment: OS: macOS Sierra 10.12.6 Node: 6.10.3 Yarn: 1.0.2 npm: 3.10.10 Watchman: 4.7.0 Xcode: Xcode 8.3.3 Build version 8E3004b Android Studio: Not Found
Packages: (wanted => installed) react: 16.0.0-alpha.12 => 16.0.0-alpha.12 react-native: 0.48.3 => 0.48.3
Steps to Reproduce
- Create minimal app with a FlatList component that loads 20 items (with a height that is roughly double the height of the screen size)
- Add onEndReached prop with a handler function that adds more data to the FlatList
- Add onEndReachedThreshold prop with a value of 0.5
- Load the app with the iOS simulator or an actual device
<FlatList
data={this.state.data}
keyExtractor={(item, index) => index}
renderItem={this._renderItem}
onEndReached={this.onEndReached}
onEndReachedThreshold={0.5} />
Expected Behavior
onEndReached should not be called until the user scrolls down on the vertical FlatList.
Actual Behavior
onEndReached is called as the FlatList is loaded without any interaction from the end user. There seems to be some kind of race condition, as it only happens 50% of the time I load the screen. It is definitely reproducible with a couple refreshes.
Reproducible Demo
Preferred way to reproduce is to download my minimal repo from https://github.com/zachrnolan/react-native-flatlist-vertical and yarn install && react-native run-ios
I also created a snack here: https://snack.expo.io/HkkO0RGob. Although it seems to be a little buggy with displaying the console logs.
Detailed Findings
Since starting with React Native about a year and a half ago, I’ve always dealt with some inconsistencies or bugs with lists and infinite scroll / paging. I’ve outlined my findings with FlatList to hopefully allow other people to better understand the landscape. This could be too much detail for this particular bug report, but I think it’s helpful.
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 5 (roughly half the screen height) | 0 |
Results: onEndReached is called twice on load of the FlatList
Notes: I’m guessing that onEndReached is called after the load of FlatList since the bottom of the FlatList is in view. It seems like the user should have to interact with the FlatList before onEndReached is called. Either way, shouldn’t be called twice.
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 10 (roughly the same height as the screen) | 0 |
Results: onEndReached is called once on load of the FlatList
Notes:
- onEndReached should not be called on load
- I’m able to load more pages as I scroll down, however, it will call onEndReached multiple times if I scroll really fast. I believe this is due to the momentum issue outlined here: https://github.com/facebook/react-native/issues/14015#issuecomment-310675650
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 10 (roughly the same height as the screen) | 0.5 OR 1 |
Results: Same as above
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 10 (roughly the same height as the screen) | > 1 |
Results: onEndReached is called multiple times on load of FlatList (typically around 10 times)
Notes:
- I’ve read around on different issues that it’s best to use a number between 0 and 1. Just wanted to document how it behaves when the threshold is greater than 1
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 20 (roughly double the height of the screen) | 0 |
Results:
- Works as expected!
- Still have the momentum issue.
Notes: This would be my preferred settings, however, the app I have in production is for both iOS and Android. These settings have another issue on Android (see below). I could check for Platform, so that may work.
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
iOS | 20 (roughly double the height of the screen) | 0.5 |
Results:
- Works as expected!
- Still have the momentum issue.
- 50% of the time, onEndReached is called once on load of the FlatList (not good)
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 5 (roughly half the screen height) | 0 |
Results:
- onEndReached is called once on load of the FlatList
- onEndReached is not called again when scrolling
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 10 (roughly the same height as the screen) | 0 |
Results: Android works as expected the first time you load more. However, it will not load a second time after you scroll to the bottom with the new data loaded. onEndReached function is not called.
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 10 (roughly the same height as the screen) | 0.5 OR 1 |
Results:
- onEndReached is called once on load of the FlatList (should not be called until scrolling to the bottom of the list)
- Once you scroll down and onEndReached is called twice (should only be called once)
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 10 (roughly the same height as the screen) | > 1 |
Results: onEndReached is called multiple times on load of FlatList (typically around 5 times)
Notes:
- I’ve read around on different issues that it’s best to use a number between 0 and 1. Just wanted to document how it behaves when the threshold is greater than 1
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 20 (roughly double the height of the screen) | 0 |
Results:
- onEndReached isn’t called on load (good)
- onEndReached isn’t called when I scroll to the bottom of the list (bad)
Platform | Number of Items | onEndReachedThreshold |
---|---|---|
Android | 20 (roughly double the height of the screen) | 0.5 |
Results:
- Works as expected!
Issue Analytics
- State:
- Created 6 years ago
- Reactions:105
- Comments:67 (4 by maintainers)
Top GitHub Comments
Thanks for posting this! It looks like you may not be using the latest version of React Native, v0.53.0, released on January 2018. Can you make sure this issue can still be reproduced in the latest version?
I am going to close this, but please feel free to open a new issue if you are able to confirm that this is still a problem in v0.53.0 or newer.
How to Contribute • What to Expect from Maintainers
I found this same issue - try putting
onEndReached
function call in an anonymous function.