getItemLayout requests index -1
See original GitHub issueDescription:
So we have a problem with the FlatList
, to be precise with the underlying VirtualizedList
. The list renders, jumps to the specified initialScrollIndex
but then moves away after seemingly rendering the next batch (I Imagine those are items which are added above). So I started reading through the code and encountered this section:
https://github.com/facebook/react-native/blob/78de0865cfd1540c267d35b297636d3e56894f14/Libraries/Lists/VirtualizedList.js#L999-L1001
This doesn’t make sense to me and I tried replacing it with:
const lastInitialIndex = this.props.initialScrollIndex
? this.props.initialScrollIndex - 1
: this.props.initialNumToRender - 1;
This causes that the list initially renderers incorrectly (at the start), but then afterward jumps to the correct index (it continues to reload a few times and jumps around but it ends up correct!).
My co-worker then decided that this -1
had to be some sort of placeholder so we traced it and found out that it ends up inside the getItemLayout
function where I’ve just returned this:
if (index === -1) return {index, length: 0, offset: 0};
What is the meaning of -1
and why is my list not staying at the correct position after adding further batches?
React Native version:
System:
OS: macOS 10.15.3
CPU: (4) x64 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
Memory: 366.99 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.13.1 - /usr/local/bin/node
npm: 6.14.1 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK:
API Levels: 23, 26, 28, 29
Build Tools: 28.0.3, 29.0.0, 29.0.2
System Images: android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Intel x86 Atom_64, android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
Android NDK: 17.2.4988734
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.5977832
Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.5 => 0.61.5
Steps To Reproduce
If this is needed I need to create a whole new project and figure out if I can actually reproduce this. I think this is also effected by the fact that our items do not all have the same size. The values in getItemLayout
are (AFAIK) correct, as initially it jumps to the correct position and if we disable this asynchron loading stuff with disableVirtualization={true}
and scroll to the correct index with scrollToIndex
it works.
Expected Results
Scroll to the correct item and stay there. Also, what is expected in return for array index -1?
References
apparently this has been open before and was pretty much ignored https://github.com/facebook/react-native/issues/18743
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:13
This issue is still occurring. When getItemLayout is initially called it passes -1 for the first index and the flatlist renders at an initialIndex 1 too high. Then getItemLayout is re called for all of the rendered items, starting with index 0 this time, and the flatlist rerenders to the correct initial index. This is a blocker and cannot be fixed on my side. Would love for someone to look into this. Including a condition for if (index === -1) then return { length: 0, offset: 0, index} fixes the issue but shouldn’t be needed.
This is still a problem, just giving this a little bump so that the issue isn’t closed. The main problem seems to be returning -1, I don’t know enough about the codebase to know why that ternary was added but I can imagine just removing it opens up a can of worms and causes even more problems.