Reputation: 23173
this is our FlatList, say hello:
<FlatList
data={this.state.dates}
...
/>
we feed it with the following dates:
this.state = {
dates: [
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
};
then when the visible date changes (onViewableItemsChanged
), if we end up to the first item (21/06/2019), we prepend data, so that the new state becomes:
dates: [
'18/06/2019',
'19/06/2019',
'20/06/2019',
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
right after we prepend the data, instead of STILL seeing 21/06/2019 (which was the date when the prepend took place) we now see 19/06/2019.
That's because below the hood, 21/06/2019 used to be index 0, but after the prepend, index 0 corresponds to 19/06/2019.
I'm trying to make it so that the day remains the same after prepending data.
Please don't tell me to use scrollToPosition
because that's a hack really, not the solution.
Is there any good solution to that problem?
Thank you
Upvotes: 15
Views: 8116
Reputation: 3856
There's a library: https://github.com/GetStream/react-native-bidirectional-infinite-scroll that allows you to both preprend or append data and preserve scroll position
It's basically an extension over the FlatList and supports all the props available for a plain FlatList
From their example usage tutorial: https://dev.to/vishalnarkhede/react-native-how-to-build-bidirectional-infinite-scroll-32ph#%F0%9F%96%A5-tutorial-chat-ui-with-bidirectional-infinite-scroll
It looks like it would be enough to just prepend that data to the top exactly like you're trying to do
Upvotes: 1
Reputation: 11
Leaving this here, since it took me a while to get a working solution/ workaround to this problem that doesn't leave a bad taste in my mouth: prepopulate the array with empty data, and then use the scrollToIndex
method.
this.state = {
dates: [
'',
'',
'',
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
};
And then:
<FlatList
data={this.state.dates}
ref={flatListRef}
getItemLayout={(data, index) => (
{length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
)}
...
/>
inside your componentDidMount:
const startingIndex = 4
flatListRef.current.scrollToIndex({index: startingIndex, animated: false, viewPosition: 0})
Upvotes: 1
Reputation: 2189
that maintainVisibleContentPosition
does not work if you prepend data while you are at a scroll position of 0 (all the way to the top). It does work if you are prepending while not a the top. Even scroll Y of 1 would be enough.
check this
Unfortunately this still an issue even in React Native 0.63.3
and has not been solved.
Upvotes: 2
Reputation: 2684
There is an undocumented prop maintainVisibleContentPosition on ScrollView
that do what you want, but unfortunately it's not working on android
I found another workaround by keep latest y offset with onScroll and also save content height before and after adding new items with onContentSizeChange and calculate the difference of content height, and set new y offset to the latest y offset + content height difference!
I've opened an issue on github also, but there is not any complete solution yet
Thanks to sgtpepper43 for undocumented iOS solution
Upvotes: 2