Lawrence I. Siden
Lawrence I. Siden

Reputation: 9369

FlatList items won't respond to touches while FlatList is loading new items

My list component looks like this:

<List>
  <FlatList
    data={films}
    renderItem={({ item }) => (
      <FilmListItem
        filmSummary={item}
        navigateToDetailsScreen={navigateToDetailsScreen}
      />
    )}
    keyExtractor={() => cuid.slug()}
    ListHeaderComponent={<Header totalResults={totalResults} />}
    ListFooterComponent={<Footer />}
    onEndReached={() => dispatchFetchPage()}
  />
</List>

The FilmListItem render function looks like this:

  render() {
    const { filmSummary } = this.props
    return (
      <TouchableOpacity onPress={this.onPress}>
        <ListItem title={filmSummary.Title} subtitle={filmSummary.Year} />
      </TouchableOpacity>
    )
  }

The FlatList loads a screen-full of items, then continues loading three more screen-fulls. But the TouchableOpacity items already rendered won't respond to touches until the FlatList has finished loading the additional pages.

Once the FlatList has finished loading, items respond to touches, but not before. If I scroll the list to the bottom and the FlatList continues loading more items, the visible items become unresponsive again.

Am I missing something?

Upvotes: 3

Views: 3226

Answers (1)

I Putu Yoga Permana
I Putu Yoga Permana

Reputation: 4220

It seems related to performance issue. My suggestions:

  1. Using pure component for your render item function. It will shallow compare, so it won't re-render that easily. performance improved.

  2. Don't use the anonymous function on your props. move it out outside render function. So every time your component re-render, that function won't re-create.

  3. add initialNumToRender={number} prop to Flatlist. It will show only those component which visible on the screen.

example code:

// 1. make sure your FilmListItem is pure component!!
class FilmListItem extends React.PureComponent {
  render() {
    // ....
  }
}

// 2. Move out all anonymouse function
_renderItem = ({ item }) => (
  <FilmListItem
    filmSummary={item}
    navigateToDetailsScreen={navigateToDetailsScreen}
  />
);

_keyExtractor = () => cuid.slug();

// render of your main component
render() {
  return (
    <List>
      <FlatList
        initialNumToRender={number} // 3. try add initialNumToRender
        data={films}
        renderItem={this._renderItem}
        keyExtractor={this._keyExtractor}
        ListHeaderComponent={<Header totalResults={totalResults} />}
        ListFooterComponent={<Footer />}
        onEndReached={dispatchFetchPage} // no need anonymouse function
      />
    </List>
  );
}

You can take a look similar performance problem in here:

https://github.com/facebook/react-native/issues/13649

Upvotes: 3

Related Questions