Comments

Displaying Large Lists Using the FlatList Component in React Native

In this blog post, we are going to utilize the FlatList component that comes out of the box with React Native to display a list of items. The FlatList component is a performant component that you can use when displaying large lists of data. Let’s learn some of the features of the FlatList component, which will give you better insight on it.

FlatList Features

The FlatList component is a performance enhanced component that is recommended to display large lists of data in React Native. Here are some of the core features of the FlatList component.

  • Performant component that renders items lazily, when they are about to appear on the screen, and removes them once they are off the screen. This saves memory and processing times, hence suitable for large lists.
  • It inherits all the ScrollView component’s properties, and hence is a complete scrollable list.
  • Supports header, footer, and separator components that can be used within the FlatList.
  • Scroll loading and scroll to index support, to scroll to a specific position within the list.
  • Multiple columns can be configured with the FlatList.
  • Lists can be displayed in horizontal mode if required.

Data to FlatList Component

Let’s learn about the implementation of the FlatList component. In this example, I have a large list of authors and the books they have written. We want to display this list in our React Native app efficiently using the FlatList.

Here is the sample array AUTHORS that contains the author details.

const AUTHORS = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    name: 'Matt Johnson',
    book: 'GraphQL Basics'
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    name: 'Will Smith',
    book: 'React Basics'

  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    name: 'Katie Hanson',
    book: 'React Native for Mobile Apps'
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    name: 'Katie Hanson',
    book: 'React Native for Mobile Apps'
  },
  {
    id: '58694a0f-2a21-471f-bd96-145571e29d72',
    name: 'Adhithi Ravichandran',
    book: 'React Native for Mobile Apps'
  },
 // ...lots of more authors and books go in here...

];

Each array element contains a unique id, the author’s name and the title of the book. This array is passed to the FlatList component using the data prop. This is a required prop to the FlatList.

Here is how we pass the data to the FlatList.

<FlatList
  data={AUTHORS}
  renderItem={renderItem} />

Required renderItem prop

We have seen how to pass the data to the FlatList. The next required prop to the FlatList is the renderItem. The renderItem takes an item from the data and renders it into the list.

The syntax to use the renderItem is shown below:

renderItem({ item, index, separators });

Here the item is an object that represents a single item from the data array that is passed to the FlatList. The index represents the unique index corresponding to the specific item. In addition we can also pass the optional separators to that can be used to highlight or unhighlight items.

KeyExtractor prop

We can also pass the optional keyExtractor prop to the FlatList. This is used to extract a unique key for a given item at the specified index. This key is used for caching and as the react key to track item re-ordering.

The syntax to use the keyExtractor props is shown below:

(item: object, index: number) => string;

Working Example

Alright, let’s now put all this together and pass the data, renderItem and keyExtractor to the FlatList component to display the list of authors below.

import React from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text, StatusBar } from 'react-native';

const AUTHORS = [/*...Contains Data array with author name, id and book ...*/];

/* Displays author info passed from renderItem */
const AuthorInfo = ({ name, book }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{'Author : ' + name}</Text>
    <Text style={styles.title}>{'Title : ' + book}</Text>
  </View>
);

const App = () => {
 /* renders each item on the list */
  const renderItem = ({ item }) => (
    <AuthorInfo name={item.name} book={item.book}/>
  );

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={AUTHORS}
        renderItem={renderItem}
        keyExtractor={item => item.id}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  item: {
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 20,
  },
});

export default App;

In the above example, we have passed the author data to the FlatList using the data prop. The renderItem method has the item prop and extracts the name and book from it and passes it on to the AuthorInfo component. Finally, the AuthorInfo component renders each author’s information. Below is the emulator displaying the list of the authors.

Separator Component

Alright, we have displayed our large list using the FlatList. It will be nice if we can include some separation between each item, to provide a better UI. To do this, FlatList provides a separator component. ItemSeaparatorComponent can be used to render a separator UI between each item. It will not be rendered on top of the very first item, or after the last item.

Let’s include the separator component to our existing code.

const App = () => {
  const renderItem = ({ item }) => (
    <AuthorInfo name={item.name} book={item.book}/>
  );

  /* Separator component rendered between each item on the list */ 
  const SeparatorComponent = () => {
  return <View style={styles.separatorLine} />
}

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={AUTHORS}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        ItemSeparatorComponent={SeparatorComponent}
      />
    </SafeAreaView>
  );
}

I have also added a style to our stylesheet, for the separator line as follows:

 separatorLine: {
    height: 1,
    backgroundColor: 'plum',
    paddingTop: 2,
  }

Let’s take a look at how our updated UI looks after the addition of the separator component.

Header and Footer Components

The FlatList component also provides header and footer component support. We can include these components to render as a header and footer to the FlatList just like we rendered the separator component. This can include text, images or any UI element that is appropriate for the header and footer of the list.

The header and footer component can be rendered by passing the ListHeaderComponent and ListFooterComponent props to the FlatList. Let’s take a look at the implementation details of these components within our example.

const HeaderComponent = () => {
  return (
    <View style={styles.sectionContainer}>
      <Text style={styles.sectionTitle}>Our List of Authors!!</Text>
    </View>
  );
};

const FooterComponent = () => {
  return (
    <View style={styles.sectionContainer}>
      <Text style={styles.title}>
        All rights reserved by Adhithi Ravichandran 2020.
      </Text>
    </View>
  );
};

Once the components are defined, update the FlatList component with the appropriate header and footer props.

<FlatList
        data={AUTHORS}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        ItemSeparatorComponent={SeparatorComponent}
        ListHeaderComponent={HeaderComponent}
        ListFooterComponent={FooterComponent}
  />

This adds the header to the top of our list and a footer to the very bottom of the list as shown below:

Header Component

Footer Component

Putting it all together!

Now let’s put all of this together and look at a working example of our Authors list. Below is the expo snack and you can click on it to view this on an Android or iOS emulator.

Additional Optimization using getItemLayout

Since the FlatList is optimized to perform better than the ScrollView, it renders items as we see them on the display. There is a caveat with approach. If you have a list with several hundred items, and scroll really fast, you may see a blank screen for a brief moment. This is a known caveat since the content is rendered asynchronously. You could scroll faster than the fill rate at times.

If you are aware of the size (height or width) of the items that are in the FlatList then we can add an additional optimization using the getItemLayout method. By passing the size of the items ahead of time, we can skip the measurement of the content while it is being rendered. This is a great performance boost to your FlatList.

getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}

But keep in mind, that we cannot use this if we don’t have fixed size for the items in the list.

Summary

Alright that’s a wrap to our blog post. You are in a good spot to start using the FlatList component within your React Native app.

The example used in this blog post can be accessed from my expo snack below:

FlatList Component Working Example – by Adhithi Ravichandran

I hope you enjoyed this article. See you again with more articles. If you liked this post, don’t forget to share it with your network. You can follow me on twitter @AdhithiRavi for more updates or if you have any questions.

If you are looking for a course that teaches your React Native from start to finish, checkout Mosh’s course linked below:

Ultimate React Native Course – Code With Mosh

Adhithi Ravichandran is a Software Consultant based in Kansas City. She is currently working on building apps with React, React Native and GraphQL. She is a Conference Speaker, Pluralsight Author, Blogger and Software Consultant. She is passionate about teaching and thrives to contribute to the tech community with her courses, blog posts and speaking engagements.
Tags: , , , , ,

Leave a Reply

Connect with Me
  • Categories
  • Popular Posts

    %d bloggers like this: