React Native Essentials: How to use Flatlist

React Native Essentials: How to use Flatlist

In this article of our series “React Native Essentials”, we have a look at a React Native component called Flatlist.

But what exactly is a FlatList? In simple terms, FlatList is a list component that is used to render long lists of data with similar structures, offering efficient performance even with large datasets.

It’s a fundamental tool for building mobile apps because most of the time we have to display scrollable lists of items in our apps. As such, understanding how to use Flatlist is crucial for every React Native developer.

Why Use FlatList?

When you start creating lists in React Native, one of the first questions you may ask is, “Why should I use FlatList?” The reason why FlatList is the go-to choice for developers boils down to two key aspects: its superior performance and its useful built-in features.

Performance Benefits: Unlike the ScrollView component in React Native, FlatList shines when handling long lists of data. The component renders only the items currently visible on the screen, a technique known as ‘lazy loading’. This dramatically enhances the performance of your app when dealing with extensive data sets.

Features and Capabilities: It supports both vertical and horizontal modes, includes header and footer support, allows for item separation, and even incorporates pull-to-refresh and infinite scroll functionalities. These built-in capabilities mean you can achieve more without having to reinvent the wheel.

Getting Started with FlatList

The first step to using FlatList is to import it from the react-native package in your file. This is done using the following line of code:

import { FlatList } from 'react-native';

Once imported, you can use it within your component as follows:

<FlatList
  data={YOUR_DATA_ARRAY}
  renderItem={YOUR_RENDER_ITEM_FUNCTION}
  keyExtractor={item => item.id}
/>

In the code snippet above, YOUR_DATA_ARRAY is an array containing the data you want to display. YOUR_RENDER_ITEM_FUNCTION is a function that returns a React component to render for each item in the array. The keyExtractor prop is a function that takes an item from the data array and returns a unique key for that item. This key is used by React to keep track of each item in the list and its changes.

In the following section, we’ll go into more detail about some key FlatList props and how to render items with FlatList.

Some FlatList props you will use almost every time

These props allow you to customize the functionality of the FlatList component according to your needs :

data: This is an array containing the data to be rendered. Each item in the array will be turned into a row in the FlatList.

data={YOUR_DATA_ARRAY}

renderItem: A function that returns a React component to render for each item in the array. The function is passed an object containing the item data, so you can tailor the rendered component for each item.

renderItem={({ item }) => <Text>{item.title}</Text>}

keyExtractor: This function takes an item from the data array and returns a unique key for that item. This key helps React to identify which items have changed, are added, or are removed. This is very important so that React can optimize the rendering of the list.

keyExtractor={item => item.id.toString()}

numColumns: You can display items in multiple columns by using this prop. By default, the list is a single column, but by setting numColumns to any number, you can create a grid-like layout.

numColumns={2} // This creates a two-column layout

onEndReached: This function is called once the scroll position gets within onEndReachedThreshold of the rendered content. It’s useful for implementing “infinite scroll” functionality.

onEndReached={() => fetchMoreData()}

ListHeaderComponent, ListFooterComponent and ListEmptyComponent: These props can be used to render a header component at the beginning of the list, a footer component at the end of the list, and a placeholder when the array of the prop data is empty.

ListHeaderComponent={() => <View style={styles.header} />}
ListFooterComponent={() => <View style={styles.footer} />}
ListEmptyComponent={() => <Text>There is no data to displlay</Text>}

These are just some of the props of the FlatList component that we use most of the time in my experience. I haven’t covered all of them so make sure to have a look at the official docs to learn about all the possibilities of Flatlist.

How to Render Items with FlatList

In your FlatList component, the renderItem prop is responsible for rendering each item. This prop expects a function that returns a component. This function is invoked with an item from the data array as an argument.

Here’s a basic example:

<FlatList
  data={data}
  renderItem={({ item }) => <Text>{item.title}</Text>}
  keyExtractor={item => item.id}
/>

Here data is an array of objects where each object has an id and a title. The renderItem function receives an object and destructures the item property from it. This item corresponds to each object in your data array.

What if you wanted to render a more complex layout for each item, not just a text component? You can return any React component from the renderItem function. For example:

<FlatList
  data={data}
  renderItem={({ item }) => (
    <Pressable onPress={() => handleItemClick(item.id)}>
      <View style={styles.item}>
        <Text style={styles.title}>{item.title}</Text>
        <Text style={styles.description}>{item.description}</Text>
      </View>
    </Pressable>
  )}
  keyExtractor={item => item.id}
/>

In this snippet, each item is rendered as a view containing two text components, one for the title and one for the description. The item is wrapped in a Pressable component to handle clicks. The handleItemClick function is called when an item is pressed. The function could navigate to a new screen, open a modal, or perform any other action you need.

This is the basic pattern for rendering items with FlatList. As you can see, it provides a flexible way to display data, allowing you to easily customize the layout of each item. You can even include interaction logic within your rendered components, such as buttons or gesture responders, which we’ll explore in the next section.

Optimizing FlatList Performance

While FlatList offers many benefits, including high performance with long lists, there are times when you might need to optimize its performance even further. Here are a few tips to help you ensure your FlatList component is running as smoothly as possible:

Use the keyExtractor Prop Correctly: As previously discussed, keyExtractor is a function that takes an item from the data array and returns a unique key. Providing a unique key is important for efficient re-renders if your data changes.

<FlatList
  data={data}
  renderItem={({ item }) => <Text>{item.title}</Text>}
  keyExtractor={item => item.id.toString()} // This is a unique Id
/>

Leverage shouldComponentUpdate: Avoid unnecessary re-renders by leveraging the shouldComponentUpdate lifecycle method or React.memo if you’re using functional components so that you can prevent your component from re-rendering unless there’s a change in props.

Avoid Inline Functions in Props: Inline functions can cause unnecessary re-renders, as they’re recreated on each render. Instead, define your functions outside the component or use the useCallback hook for functional components.

const renderItem = useCallback(({ item }) => <Text>{item.title}</Text>, []);

<FlatList
  data={data}
  renderItem={renderItem}
  keyExtractor={item => item.id.toString()}
/>

Use getItemLayout for Fixed Height Lists: If you know in advance the height of each item in your list, use the getItemLayout prop. This eliminates the need for the FlatList to measure every item dynamically.

<FlatList
  data={data}
  renderItem={({ item }) => <Text>{item.title}</Text>}
  keyExtractor={item => item.id.toString()}
  getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}
/>

It’s good to know these techniques, but you should only use them if you’re experiencing performance issues. React Native’s FlatList is designed to be performant right out of the box.

Premature optimization is the root of all evil! 🙂

Examples of Use-Cases FlatList in real life

The versatility of the FlatList component makes it suitable for a range of applications in React Native projects. Here are a few examples of how you could potentially use FlatList.

1. Displaying a List of Users: If you’re building a social media app, you might need to display a list of users. FlatList can be used to efficiently render each user with custom components including their profile picture, name, and bio.

<FlatList
  data={users}
  renderItem={({ item }) => (
    <View style={styles.user}>
      <Image source={{ uri: item.profilePicture }} style={styles.image} />
      <Text style={styles.name}>{item.name}</Text>
      <Text style={styles.bio}>{item.bio}</Text>
    </View>
  )}
  keyExtractor={item => item.id}
/>

2. Product Catalog: For e-commerce applications, FlatList is ideal for rendering product catalogs. Each product can be displayed with its image, name, and price, along with a button for adding the product to the shopping cart.

<FlatList
  data={products}
  renderItem={({ item }) => (
    <View style={styles.product}>
      <Image source={{ uri: item.image }} style={styles.image} />
      <Text style={styles.name}>{item.name}</Text>
      <Text style={styles.price}>${item.price}</Text>
      <Button title="Add to Cart" onPress={() => addToCart(item)} />
    </View>
  )}
  keyExtractor={item => item.id}
/>

3. News Feed: In a news app, FlatList can be used to display a list of news articles. Each article can be displayed with a headline, summary, and thumbnail image. Clicking on an article could navigate to a detailed view.

<FlatList
  data={articles}
  renderItem={({ item }) => (
    <Pressable onPress={() => navigateToArticle(item.id)}>
      <View style={styles.article}>
        <Image source={{ uri: item.thumbnail }} style={styles.image} />
        <Text style={styles.headline}>{item.headline}</Text>
        <Text style={styles.summary}>{item.summary}</Text>
      </View>
    </Pressable>
  )}
  keyExtractor={item => item.id}
/>

Frequently Asked Questions (FAQ)

What is the difference between FlatList and ScrollView?

FlatList and ScrollView both allow users to scroll through content, but they’re used in different scenarios. ScrollView renders all children immediately, making it suitable for a small number of children. FlatList, on the other hand, is more performance-optimized and only renders the items currently visible on the screen, making it ideal for large lists of data.

Why is my FlatList not rendering any items?

This could happen for a number of reasons. First, check if your data prop is an array and not null or undefined. Second, make sure your renderItem function is correctly returning a component. Lastly, ensure each item in your data array has a unique key.

Can I use FlatList with data from an API?

Yes, you can use FlatList with data from an API. The data prop of FlatList accepts an array, so as long as you transform your API data into an array format, you can render it with FlatList.

How can I add headers and footers to a FlatList?

FlatList provides ListHeaderComponent and ListFooterComponent props for this purpose. You can pass a React Component or a function that returns a React Component to these props.

Can FlatList handle multiple columns of data?

Yes, FlatList has a numColumns prop that can be used to render multiple columns of data. This prop accepts an integer and will cause your items to be rendered in rows with the given number of columns.

Why does my FlatList scroll performance feel slow, and how can I improve it?

FlatList performance can be affected by various factors including complex rendering of items, large datasets, and inefficient re-renders. Refer to the ‘Optimizing FlatList Performance’ section of this article for tips on how to improve performance.

How can I highlight the selected item in a FlatList?

To highlight the selected item in a FlatList, you’ll need to manage a piece of state in your component that keeps track of the selected item. In your renderItem function, you can then change the styling of the item component based on whether it matches the selected item.

How do I implement pull-to-refresh in FlatList?

FlatList has built-in pull-to-refresh functionality that can be enabled with the refreshing and onRefresh props. The refreshing prop accepts a boolean indicating whether a refresh operation is happening, and onRefresh accepts a function to be called when the pull-to-refresh gesture is activated.

Can I use FlatList inside another FlatList or ScrollView?

While it is technically possible to nest a FlatList inside another FlatList or ScrollView, it’s generally not recommended as it can lead to unpredictable behavior, especially with scroll events.

How to add spacing or padding between items in a FlatList?

To add spacing or padding between items in a FlatList, you can style your item component with a margin or padding. Alternatively, use the ItemSeparatorComponent prop of FlatList to render a separator component between each item.

Conclusion

FlatList is a powerful, flexible, and efficient component for rendering large lists in React Native applications.

It’s a component you will use almost every time when buildings UIs with lists of items.

With this guide, you are now well-equipped to start using FlatList in your projects, rendering complex lists of data, handling user interaction, and even optimize performance when needed.

I hope you found this guide helpful! For more React Native resources, tips, and tutorials, be sure to stay tuned to React Native Central.

Looking forward to seeing you in the next post!

To further your understanding of React Native, have a look at some of our other articles:

Scroll to Top