How to build an "infinite" list in ReactNative


Hello, I'm an iOS engineer working at Retty, Inc.
In the last few months, we have re-created our iOS application with Swift & ReactNative.
And we have decided to create the list of user's posts with ReactNative.

# Lists in ReactNative
When talking about a list in ReactNative, we have three different choices.
1. [ListView](https://facebook.github.io/react-native/docs/listview.html)
2. [FlatList](https://facebook.github.io/react-native/docs/flatlist.html) & [SectionList](https://facebook.github.io/react-native/docs/sectionlist.html)
3. Third-party libraries (e.g. [recyclerlistview](https://github.com/Flipkart/recyclerlistview))

## FlatList & SectionList
As FlatList & SectionList is recommended by the official site of ReactNative, and because I want to show some section headers on my list, I tried SectionList first.
It has a very nice interface, and you can build a list with section headers, `RefreshControl` and infinite scroll without any effort.

```javascript
      <SectionList
        style={styles.list}
        sections={sections}
        extraData={this.state}
        keyExtractor={this.keyExtractor}
        renderSectionHeader={this.renderSectionHeader}
        renderItem={this.renderItem}
        enableEmptySections
        legacyImplementation
        stickySectionHeadersEnabled
        refreshing={false}
        onRefresh={this.onRefresh}
        onEndReached={this.onEndReached}
      />
```
Just that, you can build a very "nice" list.
But the problem comes now, I found sometimes there are blank cells showing up when scrolling the list, with a very quick scroll, there will be lots of blank cells.
It's so weird, as an answer, I found that

> Different from `ListView`, in order to resolve the memory issue of `ListView`, `FlatList` & `SectionList` are built based on a virtualized listview.
> The virtualized listview unmounts views that have gone out of the viewport, and it relies on `ScrollView` to do its layout and appropriately replaces unmounted views with blank views.

Okay, here is the reason why I can see blank cells when scrolling.

## ListView
After lots of research on how to improve `SectionList` (actually there is not so much information about it), I decided to give it up, and give `ListView` a try.
In the latest version of ReactNative, `ListView` has already been DEPRECATED.
The reason is `ListView` has a memory issue when building a large list. I don't know what's the definition of "large list" here, so I decided to have a try.
Actually `ListView` has almost the same interface and functionalities comparing with `SectionList`.

```javascript
      <ListView
        style={styles.list}
        dataSource={this.state.dataSource}
        renderSectionHeader={this.renderSectionHeader}
        renderRow={this.renderRow}
        enableEmptySections
        stickySectionHeadersEnabled
        refreshControl={
          <RefreshControl
            refreshing={false}
            onRefresh={this.onRefresh}
          />
        }
        onEndReached={this.onEndReached}
      />
```
That's it, not many changes.
I tested it with my account, `ListView` works very fine, even it's difficult to find the difference between `ListView` and ListViews of pure native implementation.
At this point, I didn't know why `ListView` has been deprecated, it works absolutely better than "new" `SectionList`.
And we released the `ListView` version to Apple store.
After a couple of days, I got several crash reports of this part. From the crash report, I found it crashes when displaying a user's post list with over 4,000 posts, and the reason is `memory issue`.
By checking Xcode's memory graph, I realized that when I scroll down the list, the memory usage keeps growing. It reaches 500 MG after scrolling to over 500 posts, it's very very bad performance. And after scrolling to over 500 posts, the application crashes on an iPhone6.
Now, I know what is the "memory issue" of `ListView` talking about.
After reading some source code of `ListView`'s implementation, I got the answer

> 1. `ListView` doesn't reuse cells.
> 2. There is also no virtualization of any kind, leading to huge increase in memory usage as you scroll down a practically infinite list.
> 3. There is one more problem is that listview listens to scroll event and renders items as you scroll down, this is great but it also means if you scroll too quickly the scroll would come to halt before items are rendered.

Oops, I shouldn't put it into production at all.

## Third-party libraries
There are tons of third-party libraries, but most of them are built based on `ListView` or `FlatList` & `SectionList`, means that no one is really resolving those problems.
There are also some libraries like [recyclerlistview](https://github.com/Flipkart/recyclerlistview), they have their own implementation of the listview, but most of them have the almost same concept of the virtualized listview, which also has the same problems remaining not resolved.

## Conclusion
As a very positive supporter of ReactNative, I don't like to but I have to draw a conclusion, that 

> It's not possible to build a large list in ReactNative!

I really hope someone can overthrow my conclusion, but now I have to decide to re-implement all the stuff in pure native.