1
votes

I am building a feed using FlatList in React Native. I have paginating and fetching 10 rows per page by making async calls to the server.

I am using the onEndReached and onEndReachedThreshold to call a function that fetches the data for the next page. The page number and the data for the feed are stored in the component state.

When I receive the data from the server, I concatenate to the data in the state. The flatlist data prop is set to the data in the state.

However, when I browse through the feed, I experience jittery behavior and the feed is not smooth.

I am using Pure component to render the feeditems. However, each feed item has some state in it as they are interactive components.

One way to get around the jittery behavior was to put the flatlist inside a scrollview. It did indeed make the feed smooth. However, now the problem is that the onEndReached event is fired for the flatlist extremely frequently. In fact, I don't even have to scroll and the flatlist onEndReached keeps firing continuously.

  1. Does anyone know how this can be stopped?
  2. Is there a best practice to build a feed in React native. Especially, if the feed items are components which are interactive and contain state?

Should I be passing all the data to the feed item as props and not have any state in them as suggested here ( https://facebook.github.io/react-native/blog/2017/03/13/better-list-views.html)

"The internal state of item subtrees is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay"

In which case, how would I manage the state of the feed items?

Any help would be greatly appreciated.

Some code:

<ScrollView
    ref="scrollViewRef"
    style={styles.container}
    contentContainerStyle={styles.contentContainer}
    scrollEnabled={true}>
    <FlatList
      ref="listRef"
      data={this.state.content}
      extraData={this.state}
      keyExtractor={item => item.id}
      renderItem={this._renderItem}
      onEndReached={this._onEndReached}
      onEndReachedThreshold={0.2}
      onRefresh={this._onRefresh}
      refreshing={this.state.refreshing}
      ItemSeparatorComponent={this._separator}
      ListHeaderComponent={this._separator}
      ListFooterComponent={this._separator}
    />
</ScrollView>
2

2 Answers

1
votes

A few things to be aware of when using FlatList.

  1. FlatList inherently already implemented ScrollView. So you should be able to scroll through lists of data out of the box.
  2. Best to define a dimension for the component that is about to render with getItemLayout. This way you save some memory calculating the dimensions needed to render.
  3. PureComponent sometimes does not work as expected. It's better to define your own shouldComponentUpdate in your component.

I was working on a Calendar project and my data array contains hundreds of data and the result was buttery smooth. But I did have a problem only when switching between lists of data. Nonetheless, that is out of the question anyway. This problem is still unresolved.

Hope my findings help!

1
votes

Don't put FlatList inside a ScrollView. FlatList itself has a ScrollView.

Furthermore, if you have a large list, you might add one property in your FlatList like below

<FlatList
    ... 
    contentContainerStyle = {{ flex: 1 }}/>
{/* Your other properties represent those three dots '...' */}

That means adding { flex: 1 } in your contentContainerStyle might help you, just a suggestion... worked for me though.