Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlatList automatically scrolls after adding new items #25239

Open
SiSa68 opened this issue Jun 12, 2019 · 145 comments
Open

FlatList automatically scrolls after adding new items #25239

SiSa68 opened this issue Jun 12, 2019 · 145 comments

Comments

@SiSa68
Copy link

SiSa68 commented Jun 12, 2019

FlatList automatically scrolls after change data and adds new data in the front or middle of the data list.
It only works correctly when adds new item to the end of list
I checked scroll offset and understand that FlatList scrolls to keep the latest content Y offset
I mean when the content size changes, the latest Y offset now is not where the user was before! but FlatList scrolls to it

React Native version:
react-native: 0.59.4
System:
OS: Windows 7
CPU: (2) x64 Intel(R) Pentium(R) CPU G4400 @ 3.30GHz
Memory: 310.09 MB / 3.87 GB
Binaries:
Yarn: 1.15.2 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD
IDEs:
Android Studio: Version 3.2.0.0 AI-181.5540.7.32.5056338

Describe what you expected to happen:

It shouldn't scroll to new position when I add new items to list, and should keep latest position where user was

Example code:

<FlatList
inverted
style={{flex: 1}}
data={this.data}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
ref={ref => this.flatList = ref}
/>

Code that adds new items to list:

this.data = [ ...newItems, ...this.data ];

@sgtpepper43
Copy link

If you only need this fixed in ios, there's an undocumented prop maintainVisibleContentPosition on ScrollView that ought to do what you want. Unfortunately it doesn't work on android. I've been trying to solve this problem for the last two days in my own code and it's a freaking nightmare.

@SiSa68
Copy link
Author

SiSa68 commented Jun 22, 2019

@sgtpepper43 Thank you for participate
I need in both android and iOS.
I find 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!

But its not a good way, because it has UX problem. Firstly it scrolls down and after that scrolls back to the latest position
And it's not working when I want to load my list item from realm database

There should be a simpler way to do this and I don't understand why there is not?!

@sgtpepper43
Copy link

That's the same point I'm at 😩 I was going to try and fix it, but it's taken longer to try to get the Android code building and running in our app then writing the fix itself will take... I still haven't gotten it to compile. So I'm giving up on that.

@SudoPlz
Copy link
Contributor

SudoPlz commented Jul 1, 2019

fyi, I've asked the same thing here https://stackoverflow.com/questions/56707931/prepending-data-to-a-flatlist-always-shows-the-first-child/56837491#56837491

No actual fixes so far.

Leaving that here for future reference.

@winardis
Copy link

having the same issue here on trying to prepend data to my datasource,
i found "maintainVisibleContentPosition" but that only works for IOS, Android is not supported
have you guys found any other solutions on this without manually scrollToIndex of course

@kirillpisarev
Copy link

kirillpisarev commented Jul 22, 2019

I was afraid that there is no straightforward way to achieve this, but at the moment after a couple of days of trying to implement this feature, it looks like RN is not an appropriate tool to implement chat apps.

@SiSa68
Copy link
Author

SiSa68 commented Jul 22, 2019

I can not believe that they are not support this feature at all!!!
I found RecyclerListView
It might solve this problem, But I didn't currently have the opportunity to test it
If someone has an opportunity, please test and give the result to the React Native community!

@jmacioszek
Copy link

That's an issue for me as well, would be nice to have this working with SectionList.

@AVert
Copy link

AVert commented Aug 14, 2019

Have same problem Guys ((
maintainVisibleContentPosition not work on Android

@SudoPlz
Copy link
Contributor

SudoPlz commented Aug 14, 2019

I created a ticket in Canny, please upvote, this has to get fixed soon https://react-native.canny.io/feature-requests/p/allow-prepending-new-items-to-flatlists-without-side-effects

@AVert
Copy link

AVert commented Aug 26, 2019

@sahrens
Could you please triage this? This is a regression/bug, right? If so, any advice how to fix it? Thanks!

@AVert
Copy link

AVert commented Aug 28, 2019

i check this same way not work

I can not believe that they are not support this future at all!!!
I found RecyclerListView
It might solve this problem, But I didn't currently have the opportunity to test it
If someone has an opportunity, please test and give the result to the React Native community!

@AVert
Copy link

AVert commented Aug 28, 2019

I can not believe that they are not support this future at all!!!
I found RecyclerListView
It might solve this problem, But I didn't currently have the opportunity to test it
If someone has an opportunity, please test and give the result to the React Native community!

@naqvitalha can you change you component to mak it work as we need?

@AVert
Copy link

AVert commented Aug 29, 2019

I can not believe that they are not support this future at all!!!
I found RecyclerListView
It might solve this problem, But I didn't currently have the opportunity to test it
If someone has an opportunity, please test and give the result to the React Native community!

I try this - no way

@woody-riddle
Copy link

@AVert
Thanks for your try.
If you fix it, let's talk how you use that instead of ScrollView and maintainVisibleContentPosition.
I will try that too.
Best wishes for you.

@dmkerfont
Copy link

dmkerfont commented Oct 10, 2019

Clarification: I'm creating a chat app which will append pages of messages as user scrolls up, and prepend newly received messages to the bottom.

My solution using an inverted flatlist was to not render newly received messages at the bottom, unless/until the user is scrolled to the bottom.
Here's how I achieved that:

  1. Add following component state variables

    • isScrolledBottom: boolean
    • newMessageList[]
  2. define a threshold for deciding if we are scrolled to bottom of list
    myThreshold = 100 pixels

  3. Create a method for handling onBottomReached while scrolling
    onBottomReached()
    {
    if(newMessageList > 0){
    - append them to my flatlist data source
    - remove them from my newMessageList in component state
    - scroll to bottom
    }
    }

  4. flatlist onScroll:
    if (crossed 100px threshold, in either direction)

    • if at bottom, then call onBottomReached()
    • set state.isScrolledToBottom = T/F
  5. New message received:
    if(at bottom){
    append to flatlist data source
    }
    else{
    append to newMessageList
    }

This gave me the best user experience, since maintainVisibleContentPosition does not work on android, so I did not use it at all.

@SudoPlz
Copy link
Contributor

SudoPlz commented Oct 10, 2019

@dmkerfont I don't really get it, what problem does this solve? It looks like you're not "prepending" data, looks like you're only appending.

Isn't the issue only apparent when someone tries to prepend data (and thus get's scrolled on a wrong date?)
Have I miss-understood something?

Thanks

@dmkerfont
Copy link

@SudoPlz
With an inverted flatlist. The 'end' of the list is actually the top, thus scrolling up will continue to add older pages ( appending to the end ).

When a new message comes in, prepending it to the front of the list will cause the data shifting issue as the indexes are reset.

Instead of prepending every message that comes in, I'm checking if the user is at/near the bottom or if they are scrolled up a significant distance.

If at bottom, then prepend and scroll down.
Else, build a queue of messages to prepend.

If user reaches bottom, through a manual scroll or pressing a button like a 'New Message' indicator, then simply prepend the queued messages.

I have no experience with native code so I have no desire to implement maintainVisibleContentPosition at this time, but this is a decent workaround.

@SudoPlz
Copy link
Contributor

SudoPlz commented Oct 10, 2019

@dmkerfont interesting, is it too much to ask for some visual example? I've taken the time to replicate what you said with numbers below, does it look right?

Example:

Inverted flatlist

[3]
[2] <-- Index 2 / User sees 2
[1]
[0]

user manually scrolls to the bottom, then:

[3]
[2] 
[1]
[0]<-- Index 0 / User sees 0

New items [4][5][6] get prepended:

[3]
[2] 
[1]
[0]
[4]
[5]
[6]<-- Index 0 / User sees 6

so the user ends up seeing [6] now (which is now index 0) .

Then as an extra step the user get's scrolled to 0 again?

  • Isn't that a problem? Shouldn't the user see [4] instead? (index 2) ? since it's the next item after [0] ?
  • Also another question, does appending (adding items after [3]) work fine using an inverted list?

I appreciate your time, thanks.

@dmkerfont
Copy link

@SudoPlz

Isn't that a problem? Shouldn't the user see [4] instead? (index 2) ? since it's the next item after [0] ?

Shoot... You are right. If I'm scrolled up (and want my scroll position preserved), then I build my list of new messages.
Once I scroll down manually, when I hit the bottom and the list [4][5][6] is prepended, I'm suddenly staring at item [6] instead of [4]. This means that the issue still exists, but you will only notice it if you are prepending more than 1 or 2 items to the list at a time while scrolling.

Perhaps this alternative isn't worth all the effort after all. :(

Also another question, does appending (adding items after [3]) work fine using an inverted list?

If you've done any paging, you will have noticed that adding items to the end of the list ( bottom for regular flatlist ) works as expected. This is the same when appending (top) to an inverted flatlist.

@SudoPlz
Copy link
Contributor

SudoPlz commented Oct 10, 2019

Ok cool, please let me know if you find a way to make the user see [4] instead (the next item).

@jesster2k10
Copy link

What’s the story with this issue? Every time the data source on the flat list changes, say once new data is fetched or prended to the list it resets the scroll position. I’m building some sort of user feed, so I need to be able to update the data source without messing up the users scroll position.

Is this possible at all with react native? The maintainVisibleContentPosition prop seems to do nothing for me.

@jakovB777
Copy link

jakovB777 commented Nov 25, 2019

Edit: As Sisa68 noted, I misunderstood the struggle here. Mb

@SiSa68
Copy link
Author

SiSa68 commented Nov 26, 2019

@jakovB777 I think our case are different from yours!
We want to add item to both side of list, not only push on back.
There is no problem when you have one side list with FlatList

@isuhar
Copy link

isuhar commented Nov 26, 2019

Same problem =(( We add new items to the start of array and position is still 0

@toddrimes
Copy link

This works for me:

Screen Shot 2019-12-06 at 9 44 51 AM

@meosieudang
Copy link

anyone fix it?

@Donhv
Copy link

Donhv commented Dec 25, 2019

i use https://github.com/bolan9999/react-native-largelist and same issue.

@Villefor
Copy link

@friedolinfoerder Hello ! Thanks for sharing your solution, can you tell me if onEndReached is enabled in your flatlist ?

@friedolinfoerder
Copy link

@Villefor it is a replacement solution for FlatList which uses FlatList under the hood, so yes, almost all properties of FlatList (including onEndReached) are supported. What can and maybe will be added in a future version is an onStartReached property which will fire when reaching the upper part of the list.

@Choyeongdeok
Copy link

in ios use maintainVisibleContentPosition
in android wait this pr #35049

@aarononeal
Copy link

Is maintainVisibleContentPosition working for folks on iOS? Inserting or removing items to index 0 seems to always scroll my list to the top.

@chaitanya71998
Copy link

@jwinnfeild2517
Copy link

jwinnfeild2517 commented Aug 10, 2023

This worked for me -> If you are adding a list of items to a grid or list. Instead of creating a new array ref in state whenever new items are created. use the prevState and concat your new items. The reason your Flatlist scrolls to the bottom of your new items is that you are creating a new arr/list reference. The Flatlist will attempt to keep your scroll position within the new array ref. However, by adding to the prev ref of your array, you will be kept in the same position.

setItems((prevState) => prevState.concat(newItems));

@arnavr15
Copy link

If you only need this fixed in ios, there's an undocumented prop maintainVisibleContentPosition on ScrollView that ought to do what you want. Unfortunately it doesn't work on android. I've been trying to solve this problem for the last two days in my own code and it's a freaking nightmare.

But in case of prepending new data to existing one, it doesn't work in ios as well.

@saif-o99
Copy link

saif-o99 commented Sep 7, 2023

maintainVisibleContentPosition doesn't work to me. any other fix after 5 years?

@benkhlifafahmi
Copy link

@saif-o99 i guess the best option would be as @SudoPlz suggested is to create your own crousel, i tried different solutions but it seems that appending data to the start of the list will absolutely make you lose the current viewable item.

@ahmed-sharief5
Copy link

Hi guys,
I was also facing the same issue and i found a working solution. Just use

initialNumToRender: data.length

this resolved the flatlist scroll fluctuation. I hope this works for you guys as well

@benkhlifafahmi
Copy link

benkhlifafahmi commented Sep 15, 2023

@ahmed-sharief5 but i believe this will affect the app performance, specially for people with large data/paginated data.

@ahmed-sharief5
Copy link

@benkhlifafahmi otherwise use

maxToRenderPerBatch: data.length

Because it determines the maximum number of items to render in each batch when new items are loaded during scrolling. A higher value can reduce the number of render cycles and improve performance

@yurijdvornyk
Copy link

Haha, any fix for November 2023?

@RobertMrowiec
Copy link

I'm looking for a solution too without creating own carousel... Some time ago it worked for me with 'maintainVisibleContentPosition' but for some reason it stopped...

@chaitanya71998
Copy link

try this one it works https://github.com/GetStream/react-native-bidirectional-infinite-scroll

did you check this?

@IordanisSap
Copy link

How has that issue never been resolved after so many years?

@jalterin
Copy link

jalterin commented Jan 8, 2024

I found a solution. Just put your FlatList inside a SafeAreaView with flex:1
<SafeAreaView style={{flex: 1}}> <FlatList/> <SafeAreaView>

It worked for me android and ios

@RobertMrowiec
Copy link

RobertMrowiec commented Jan 8, 2024

I found a solution. Just put your FlatList inside a SafeAreaView style={{flex: 1}} It worked for me android and ios

You sure? It doesn't make sense in terms of fixing the following issue...

@jalterin
Copy link

jalterin commented Jan 8, 2024

I found a solution. Just put your FlatList inside a SafeAreaView style={{flex: 1}} It worked for me android and ios

You sure? It doesn't make sense in terms of fixing the following issue...

Yes @RobertMrowiec . I spent more than 2 hours searching for a solution, and then I just found one of my old projects with that implemented. I had a SafeAreaView Wrapper for my all screens, and I tried tried and it's working fine.

@fabOnReact
Copy link
Contributor

I can fix this issue using the new API maintainvisiblecontentposition has been added to Android with https://github.com/facebook/react-native/pulls?q=is%3Apr+author%3Ajanicduplessis+is%3Aclosed+maintain. The issue is pretty old. Anybody still interested in this? Thanks

@fabOnReact
Copy link
Contributor

There is a new popular component FlashList with 4.5k stars. Did you try to use that component? If yes, why did you decide to keep using FlatList from react-native? Thanks

@dcnxx1
Copy link

dcnxx1 commented Jan 31, 2024

There is a new popular component FlashList with 4.5k stars. Did you try to use that component? If yes, why did you decide to keep using FlatList from react-native? Thanks

issue persists

@haileyok
Copy link
Contributor

haileyok commented Feb 2, 2024

There is a new popular component FlashList with 4.5k stars. Did you try to use that component? If yes, why did you decide to keep using FlatList from react-native? Thanks

This has not been implemented in FlashList unfortunately. There's an open pull that (supposedly, have not tested) adds it, but it has not been reviewed as of current.

@AwesomeAndrewMK
Copy link

I've managed to fix similar scroll issue in my "chat app" by making all flatListRef.current?.scrollToEnd calls synchronous and before all async calls. Because if you call it after in some cases, you may encounter "autoscroll to top issue".
Now it works great on both platforms.

@pablobarreraf
Copy link

2024 still not solved? wow

@duanbingu
Copy link

2024 still not solved? wow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests