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

Proposal to migrate to the new react-native component Flatlist component. #411

Closed
Kabangi opened this issue Mar 28, 2017 · 35 comments
Closed
Labels

Comments

@Kabangi
Copy link
Contributor

Kabangi commented Mar 28, 2017

I feel this module will heavily benefit from the new flatlist component because of the large dataset that is involved with it.

Am not sure though how we will go about inverting the component so that data get added at the bottom rather than at the top.

@kfiroo
Copy link
Collaborator

kfiroo commented Mar 28, 2017

@Kabangi we don't really need to invert the list, it is only used to keep the list scrolled to the bottom.
We could use ListView.scrollToEnd that was added on RN 0.42.0 to do it.

Want to create a PR for this? :)

@Kabangi
Copy link
Contributor Author

Kabangi commented Apr 12, 2017

@kfiroo Definitely I will give it a shot. Thanks

@radko93
Copy link

radko93 commented Apr 18, 2017

I'm in the middle of migrating gifted chat to FlatList. As Invertible Scroll View is not compatible, I tried onScrollToEnd. But invoking it on every onScrollDragEnd does not make a lot of sense. Maybe you have some ideas for that @kfiroo?

@kfiroo
Copy link
Collaborator

kfiroo commented Apr 21, 2017

@radko93 That's awesome!
What are we trying to solve here? Keeping the chat scrolled to the bottom when a new message arrives?

@radko93
Copy link

radko93 commented Apr 27, 2017

The problem with the lack of inverted-scrollview is that the FlatList starts to render messages from the top of the screen and not the bottom. This problem can't be solved by scrollToEnd.

@DavidKuennen
Copy link

Struggling with the same problem right now for my chat.

@DavidKuennen
Copy link

DavidKuennen commented Apr 29, 2017

Ok I'm close to getting this to work by using scrollToEnd({animated: false}) at the beginning and taking only the last n items of my list.
Then I'm determining whether the the list has been scrolled to the top by using the following:

onViewableItemsChanged={({viewableItems}) => {
    if (viewableItems.length > 0 && viewableItems[0].index === 0) {
        // Has scrolled to top
        // Load next 20 items from the end of the list
    }
}}

Now all that's left is to figure out how to keep the scroll position at the item that is index === 0 in onViewableItemsChanged, but it shouldn't be a problem since there are methods like scrollToItem(params: object), scrollToIndex(params: object) and scrollToOffset(params: object) provided. I'm sure I'll figure something out.

I propably have to point out that I'm using the underlying VirtualizedList and not FlatList, since I'm working with immutable data.

@brennanerbz
Copy link

Any progress on this?

@dralletje
Copy link

dralletje commented May 7, 2017

I am applying the inverted-scrollview styles myself using

<FlatList
  {...props}
  style={[style, { transform: [{ scaleY: -1 }]}]}
  renderItem={(x) => {
    let itemRef;
    return (
      <View style={{ transform: [{ scaleY: -1 }]}}>
        {renderItem(x)}
      </View>
    );
  }}
  ...
/>

In my own project now, which works.
Still I have no clue how I should keep the scroll position, as onContentSizeChange is totally unreliable when using FlatList.

@radko93
Copy link

radko93 commented Jun 6, 2017

Kind of made it work but this stops me from pushing a PR facebook/react-native#13727. If manually scroll to top and then send a message there's a blank space at the bottom of the list
image

@bartolkaruza
Copy link

bartolkaruza commented Jun 16, 2017

FlatList supports inversion now, through the inverted property out of the box; facebook/react-native@1d30f83

@Kabangi
Copy link
Contributor Author

Kabangi commented Jun 16, 2017

@bartolkaruza Really sweet thanks for the heads up, I do not think it's released yet. Seems like it was committed 3 days ago.

@radko93
Copy link

radko93 commented Jun 16, 2017

It will be there in around 1-2 months. But it's not different than the solution already posted in this issue #411 (comment) so it does not really change anything.

@bartolkaruza
Copy link

If you are using #411 (comment) , you have to add the following to make it work on Android 7

<FlatList
  {...props}
  style={[style, { transform: [{ scaleY: -1 }, {perspective: 1280}]}]}
  renderItem={(x) => {
    let itemRef;
    return (
      <View style={{ transform: [{ scaleY: -1 }, {perspective: 1280}]}}>
        {renderItem(x)}
      </View>
    );
  }}
  ...
/>

Otherwise, it will not render at all on Android 7 devices. This same issue is also there with the current ListView implementation; #486

@pewh
Copy link

pewh commented Sep 10, 2017

Hello, any progress on this?

@DavidKuennen
Copy link

DavidKuennen commented Oct 3, 2017

FlatList does now have an "inverted" property: <FlatList inverted {...} />
Got my chat working pretty well with it in combination with onEndReached for reloading.
It seems to keep the scoll position by default this way and starts rendering the items from the bottom.

Was finally able to throw out all the scoll and content size magic. It works as simple as this:

<FlatList
    inverted={true}
    data={messages}
    keyExtractor={this.keyExtractor}
    renderItem={this.renderMessage}
    onEndReached={this.takeNextMessages} />

It is also available in VirtualizedList, which happens to have an even better performance in my case, even tho the docs don't mention it yet (https://github.com/facebook/react-native/blob/a16ef18a803579c84c77df0274a148cafb83baaa/Libraries/Lists/VirtualizedList.js#L110).

@redwind
Copy link

redwind commented Oct 4, 2017

@DavidKuennen : FlatList inverted use transform scaleY:-1 to render item from bottom, so when we have data updated, FlatList auto display new item without animation scroll. Did you have any trick to make it keep last scroll position, then animation scroll to bottom when new item render ?
Thanks !!!

@DavidKuennen
Copy link

DavidKuennen commented Oct 4, 2017

@redwind I add new messages to the bottom of my list of messages and not to the top. That way, FlatList renders new messages at the bottom.

There is one drawback doing it this way tho and that is, that FlatList always rerenders all items upon receiving a new message, since that message is bumped to the bottom of the list.
But since FlatList only renders the items inside the current view area anyways, it's not really any performance hit at all.

The other advantage over doing it the other way is, that as I scroll top and trigger the onEndReached function to load older messages, those older messages are added to the top of the list and therefore getting rendered in an optimized way performance wise which allowes a smooth scrolling experience (as smooth as in WhastApp right now in my implementation).

The performance impact it would have to rerender the whole FlatList for every number of reloaded messages would be far greater than rerendering only once upon receiving a new message.

Interestingly enough it works as I expect a chat to work also for the scroll position this way. Every time I bump a new message to the bottom of my list, the scroll view is being pushed top the exact same height that new message has. Means, if I'm at the bottom of my list (seeing the newest message) and receive a message, I stay at the bottom without doing anything. If I'm not scrolled to the botton but for example half way through my chat, I keep the scroll position, as I expect it to be. Since if I manually scrolled top, I have a reason to do that and therefore would not want to have my scroll position being dragged to the bottom again, every time I receive a new message (that's also how WhatsApp works btw.).

Of course if you want to have your scroll position always at the bottom for each new message, a simple scrollToEnd on the FlatList would do I suppose.

This is from my implementation:

Writing:
Alt Text

Scrolling:
Alt Text

@Ashoat
Copy link

Ashoat commented Oct 4, 2017

I do the same thing as @DavidKuennen. It's my understanding that FlatList is able to prevent rerenders in response to prepends as long as the keys extracted by the keyExtractor prop match up.

@DavidKuennen
Copy link

DavidKuennen commented Oct 4, 2017

@Ashoat Thanks, didn't know it works like that and prevents rerender even when prepending messages. 👍

@Ashoat
Copy link

Ashoat commented Oct 4, 2017

I forgot to the mention that it only works if your items are rendered as React.PureComponent. FlatList basically just renders a list of children under a ScrollView, and the children are keyed with the key from keyExtractor. With the same key, you make sure that the old component gets the update instead of a new one getting rendered, and with React.PureComponent you make sure that a re-render only happens if the data actually changes.

Oh, and you'll also need to make sure that the individual objects contained in your FlatList's data array don't change at all, ie. a reference comparison should yield equality.

As long as the individual data objects don't change, the keyExtractor result is consistent, and you're using React.PureComponent, you should be able to prevent any rerenders in this case.

@pewh
Copy link

pewh commented Oct 12, 2017

This guy forked this repo and use flatlist (https://github.com/ptmt/react-native-gifted-chat-flat), but it only works on RN < 49, so I made fork (https://github.com/pewh/react-native-gifted-chat-flat) that work on RN 49 (didn't test on RN < 49). The performance is very good. But unfortunately it has bugs on send button on both mine and ptmt version, where FaridSafi version has no issue about it.

@RWOverdijk
Copy link

Is this still a thing? Is this going to be implemented? I might be able to help out if needed.

@ghost
Copy link

ghost commented Nov 1, 2017

+1 please

@rtman
Copy link

rtman commented Nov 1, 2017

+1 😇

@brunocascio
Copy link
Collaborator

PR would be nice!

Keep in mind: retrocompatibility.

@wizza-smile
Copy link

IMHO retrocompatibility should not be the major goal. This is an update to THE central component in this repo. If we continue to use old components no longer supported by RN, this project will age quickly!

@gavin-gmlab
Copy link

@brunocascio , created PR #629 For review and comments if any

@amirrezam
Copy link

amirrezam commented Dec 28, 2017

@redwind @DavidKuennen @Ashoat Did this issue "when we have data updated, FlatList auto display new item without animation scroll. Did you have any trick to make it keep last scroll position" solved ?

@xcarpentier
Copy link
Collaborator

#705

@masterbater
Copy link

@DavidKuennen can you share how did you manage to add three icons in the text input if the text is empty. Thanks.

@sibelius
Copy link
Collaborator

merge #705 by @xcarpentier

please tests on master

we can close this

@m-vdb
Copy link

m-vdb commented Jun 12, 2018

What else needs to be done to have a new release on npm? thanks for your work @xcarpentier and @sibelius

@thiZguy
Copy link

thiZguy commented Nov 1, 2018

npm installation still comes with ListView, any update coming soon to the package manager?

@stale
Copy link

stale bot commented Feb 12, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Feb 12, 2019
@stale stale bot closed this as completed Feb 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests