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 · 157 comments
Open

FlatList automatically scrolls after adding new items #25239

SiSa68 opened this issue Jun 12, 2019 · 157 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.

@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

@deleonjuan
Copy link

this worked for me:
this automatically scrolls to the bottom every time I add a new item to the list, or when the layout changes the size, like if I open the keyboard

 const flatListRef = useRef<FlatList<any>>(null);

  const scrollToEnd = () => {
    if (flatListRef.current) {
      flatListRef.current.scrollToEnd({ animated: true });
    }
  };

  return (
    <FlatList
      ref={flatListRef}
      onContentSizeChange={scrollToEnd}
      onLayout={scrollToEnd}
     // other props
    />

@aarononeal
Copy link

Fortunate you had a simpler case but I think most of us were interested in a solution that specifically doesn't visually scroll the list when new content is added.

@bored-yuns
Copy link

Any solutions? Can't believe it's still open lol..

@umardev500
Copy link

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

try use VirtualizedList insted of Flatlist as per 2024 it's worked

@wnadurski
Copy link

VirtualizedList for me has the same issue

@smspasha
Copy link

smspasha commented Nov 4, 2024

Still unable to find a solution. Does anyone know of some solution to this?

@renshul
Copy link

renshul commented Nov 5, 2024

Well I was hoping this would've beem resolved somewhere in the last 5 years. There still doesn't seem to be a proper solution...

@umardev500
Copy link

VirtualizedList for me has the same issue

Unfortunately it's had an issue for me too
I think we need to bump this issue to the RN team

@darkbasic
Copy link

I think we need to bump this issue to the RN team

There are over a hundreds participants in this issue: a bump is the last thing it needs. The react-native team is definitely well aware and it's simply not in their priorities at this point.

@durdevic
Copy link

Maybe this drop will move the needle (crying sarcastically)

@aarononeal
Copy link

Given how critical this kind of control is for displaying feed-based information, such as with social network content, it really undermines the value of the whole React Native platform to hit a blocker like this where you can't support infinite bi-directional scrolling of variable sized items.

My attempts at workarounds and building custom controls to perform offscreen sizing have so far produced mediocre results. Would be great if someone more versed in the stack internals could take another look at this longstanding issue.

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