FlatList in React Native

Learn how to use FlatList in React Native to display large lists of items.

In this tutorial, we'll learn how to use render lists in FlatList component, implement pull-to-refresh, infinite scrolling, and optimize list performance.

FlatList component in React Native is a performance-improved component for rendering large scrollable lists of data.

It is designed for handling big datasets with efficient memory usage and performance optimization by lazy loading content and recycling views.

Basic Usage

First, we need to import the FlatList component from the core react-native package:

import { TouchableOpacity, FlatList } from 'react-native';

Next, provide an array of data and a renderItem function to render each item.

It is also recommended to provide keyExtractor for extracting a unique key. By default it checks item.key property, then item.id, and then falls back to the index.

const data = [
  { id: '1', title: 'Item 1' },
  { id: '2', title: 'Item 2' },
  { id: '3', title: 'Item 3' },
];

const ItemComponent = ({ item }) => (
  <View>
    <Text>{item.title}</Text>
  </View>
);

export default function Example() {
  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <ItemComponent item={item} />}
      keyExtractor={item => item.id}
    />
  );
}

Pull-to-Refresh

React Native Screenshot showing FlatList async loading functionality

You can use refreshing and onRefresh props to implement the pull-to-refresh functionality in your React Native appication.

const [data, setData] = useState([
  { id: '1', title: 'Item 1' },
  { id: '2', title: 'Item 2' },
  { id: '3', title: 'Item 3' },
])
const [refreshing, setRefreshing] = useState(false);

const onRefresh = async () => {
  setRefreshing(true);
  
  // Async action to fetch new data
  const response = await fetch('https://assets.withfra.me/api/posts.json')

  setData(await response.json());
  setRefreshing(false);
};

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

Infinite Scrolling

To load more data as the user scrolls, use the onEndReached and onEndReachedThreshold props.

const [data, setData] = useState([
  { id: '1', title: 'Item 1' },
  { id: '2', title: 'Item 2' },
  { id: '3', title: 'Item 3' },
  { id: '4', title: 'Item 4' },
  { id: '5', title: 'Item 5' },
  { id: '6', title: 'Item 6' },
  { id: '7', title: 'Item 7' },
]);

return (
  <FlatList
    data={data}
    renderItem={({ item }) => <Text>{item.title}</Text>}
    keyExtractor={item => item.id}
    onEndReached={async () => {
      const response = await fetch('https://assets.withfra.me/api/posts.json')

      setData([
        ...data,
        ...await response.json(),
      ])
    }}
    onEndReachedThreshold={0.5}
  />
)

Handling Empty Lists

FlatList accepts different components to render different parts of the list. For example, you can pass a ListEmptyComponent component to render when the data array is empty.

<FlatList
  data={[]}
  renderItem={({ item }) => <Text>{item.title}</Text>}
  keyExtractor={item => item.id}
  ListEmptyComponent={<Text>No data available.</Text>}
/>

Or, you can use ItemSeparatorComponent property to render a component between items.

React Native Screenshot showing FlatList with the separator

Notice that ItemSeparatorComponent is only rendered between the items, but not at the top or bottom.

<FlatList
  data={data}
  renderItem={({ item }) => <Text>{item.title}</Text>}
  keyExtractor={item => item.id}
  ItemSeparatorComponent={
    <Text style={{ textAlign: 'center', letterSpacing: 6, fontSize: 20 }}>
      ···
    </Text>
  }
/>

Optimizing Performance

FlatList comes with several properties to optimize performance:

  • initialNumToRender - the number of items to render in the initial batch. By default it's 10, but you can change this number to fit the screen but not much more.

  • removeClippedSubviews - if you have a large list, setting this to true might improve scroll performance.

  • getItemLayout(data, index) - optional optimization function to skip content measurement step. This is only useful if all of the items have the same height (ITEM_HEIGHT in the example below).

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

We hope you enjoyed this content and now better understand how to use FlatList in React Native.

Never miss a beat

Stay in the loop with our latest updates and offers - no spam, just the good stuff!