How To Use FlatList Component In React

Master high-performance list rendering in React Native with essential props, optimization techniques, and best practices for smooth scrolling

What Is FlatList and Why It Matters

FlatList is a core React Native component designed specifically for displaying scrollable lists of items. It inherits from VirtualizedList, which implements the virtual list concept--rendering only the items currently visible in the viewport plus a small buffer above and below.

Traditional list rendering approaches face significant challenges with large datasets. When you render hundreds or thousands of items simultaneously, memory usage spikes, rendering slows down, and the user experience suffers from dropped frames and unresponsive scrolling. FlatList addresses these challenges through intelligent virtualization.

The virtualized rendering approach works by maintaining a virtual window of items around the current scroll position. As users scroll, items that exit this window are unmounted and their resources freed, while new items entering the window are rendered on-demand. This means FlatList can efficiently display lists of any size while maintaining consistent performance.

Key capabilities include fully cross-platform support, horizontal and vertical orientations, configurable viewability callbacks, header and footer support, pull-to-refresh functionality, multi-column layouts, and scroll-to-index navigation.

When to Use FlatList

FlatList excels in several scenarios:

  • Displaying variable-length lists where item count may change dynamically
  • Handling large datasets that would cause performance issues with traditional rendering
  • Implementing feeds, timelines, or any scrollable content collections
  • Creating grids using the numColumns prop for consistent multi-column layouts

For simpler use cases with small, fixed-length lists, FlatList may be overkill, and a basic ScrollView with mapped items could suffice. However, FlatList should be the default choice for any list that might grow or contains more than a handful of items.

When building React Native mobile applications, proper list implementation directly impacts user retention and app store ratings.

Basic FlatList Implementation
1import React from 'react';2import { FlatList, Text, View, StyleSheet } from 'react-native';3 4const DATA = [5 { id: '1', title: 'First Item' },6 { id: '2', title: 'Second Item' },7 { id: '3', title: 'Third Item' },8];9 10const renderItem = ({ item }) => (11 <View style={styles.item}>12 <Text style={styles.title}>{item.title}</Text>13 </View>14);15 16const MyList = () => {17 return (18 <FlatList19 data={DATA}20 renderItem={renderItem}21 keyExtractor={item => item.id}22 />23 );24};

Essential Props: Building Your First FlatList

Every FlatList requires two essential props to function: the data array containing your list items, and the renderItem function that determines how each item appears on screen.

The data Prop

The data prop accepts an array (or array-like structure) of items to render. Each item should contain enough information for renderItem to display it meaningfully. While data can be any array-like structure, typical usage involves arrays of objects with consistent properties.

The renderItem Prop

The renderItem function receives an object containing the item being rendered, its index in the data array, and separator utilities. It should return a React component representing that item's visual appearance.

The function signature provides:

  • item: The individual data item from your data array
  • index: The numeric position of this item in the list
  • separators: Object with highlight, unhighlight, and updateProps methods for customizing separators

The keyExtractor Prop

KeyExtractor is crucial for list performance. It extracts a unique string key for each item, which React uses for reconciliation and tracking item reordering. The default extractor checks item.key first, then item.id, and finally falls back to the array index.

Providing explicit keys through keyExtractor is recommended over relying on array indices, especially when items may be added, removed, or reordered. Unique, stable keys enable React Native to make optimal decisions about which items to update, add, or remove during renders.

For applications requiring complex data handling, consider how custom API integration can optimize data fetching and state management alongside FlatList implementation. When building full-stack web applications, these same principles of efficient data rendering apply across platforms.

FlatList Key Features

Everything you need to build performant lists

Virtualized Rendering

Only renders items visible in viewport, handling thousands of items efficiently

Pull-to-Refresh

Built-in refresh control for updating list content on demand

Multi-Column Support

Create grid layouts with the numColumns prop for uniform item heights

Viewability Callbacks

Track which items are currently visible for analytics or lazy loading

Enhancing FlatList: Headers, Footers, and Separators

Beyond the essential props, FlatList provides several features for creating polished list experiences.

List Headers and Footers

ListHeaderComponent and ListFooterComponent allow you to add content at the top and bottom of your list respectively. These components persist during scrolling and remain visible as users scroll through the list.

Item Separators

ItemSeparatorComponent renders content between items, typically used for visual dividers. The component receives {highlighted} and leadingItem props, allowing you to style separators differently when items are selected or during interactions.

Empty States

ListEmptyComponent renders when the data array is empty, providing a graceful fallback for users when no content exists.

These UI enhancements, combined with modern frontend practices, create seamless user experiences that rival native applications. For teams implementing AI-powered features, efficient list rendering is essential for displaying dynamic content streams.

Pull-to-Refresh and Interactive Features

Pull-to-refresh is a common mobile pattern for updating list content. FlatList implements this through the onRefresh and refreshing props.

const [refreshing, setRefreshing] = useState(false);

const onRefresh = async () => {
 setRefreshing(true);
 await fetchNewData();
 setRefreshing(false);
};

<FlatList
 data={DATA}
 renderItem={renderItem}
 onRefresh={onRefresh}
 refreshing={refreshing}
/>

The onRefresh function is called when users pull the list down past a threshold. Your implementation should trigger a data refresh and then set refreshing back to false when complete. This pattern works seamlessly with your existing data fetching logic.

Viewability Callbacks

The onViewableItemsChanged prop and viewabilityConfig allow you to track which items are currently visible in the viewport. This is valuable for analytics, lazy loading, or implementing features that depend on item visibility. Understanding these patterns is crucial for optimizing React Native performance in production applications.

Performance Impact of FlatList Optimization

90%

Reduction in memory usage with virtualization

60

Items rendered per batch by default

21

Viewport heights in virtual window (default)

Performance Optimization: Making FlatList Fly

Even with virtualized rendering, FlatList performance can suffer without proper optimization.

Configuration Props for Performance

Several FlatList props directly impact rendering performance:

removeClippedSubviews (default: true on Android, false otherwise) automatically detaches offscreen views from the native view hierarchy, reducing memory pressure and rendering overhead.

maxToRenderPerBatch controls how many items are rendered in each batch during scrolling. The default of 10 balances rendering speed with responsiveness. Higher values reduce blank areas but may cause dropped frames during rapid scrolling.

updateCellsBatchingPeriod determines the delay between batch renders. The default 50ms creates a balance between smooth scrolling and overall rendering throughput.

initialNumToRender specifies how many items to render in the initial batch. Setting this to cover the full viewport for your target devices can significantly improve perceived startup performance.

windowSize defines the virtual render window as a multiple of viewport height. The default value of 21 maintains 10 viewports above and below the visible area, plus the current viewport. Larger values reduce blank areas during fast scrolling but increase memory consumption.

Optimized FlatList Configuration
1<FlatList2 data={DATA}3 renderItem={renderItem}4 removeClippedSubviews={true}5 maxToRenderPerBatch={10}6 updateCellsBatchingPeriod={50}7 initialNumToRender={10}8 windowSize={21}9 getItemLayout={getItemLayout}10 extraData={selectedId}11/>

Optimize List Item Components

The components you render for each list item significantly impact overall list performance. Every optimization applied to item components multiplies across all visible items.

Use React.memo() to memoize your list item components, preventing unnecessary re-renders when props haven't changed:

import React, { memo } from 'react';

const ListItem = memo(({ title, onPress }) => (
 <TouchableOpacity onPress={onPress}>
 <Text>{title}</Text>
 </TouchableOpacity>
), (prevProps, nextProps) => {
 return prevProps.title === nextProps.title;
});

Avoid inline function definitions in renderItem, as these create new function instances on each render. Use useCallback to memoize the renderItem function.

Keep item components lightweight. Avoid complex layouts, unnecessary nested views, and heavy visual effects within list items.

The getItemLayout Optimization

When all list items have consistent dimensions, providing getItemLayout eliminates the need for async layout measurements:

const ITEM_HEIGHT = 80;

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

Multi-Column Layouts and Advanced Patterns

FlatList supports multi-column layouts through the numColumns prop, creating grid-like displays:

<FlatList
 data={DATA}
 renderItem={renderItem}
 numColumns={3}
 columnWrapperStyle={styles.gridRow}
/>

When using multiple columns, items should have consistent heights--masonry layouts are not supported. The columnWrapperStyle prop allows styling for rows in multi-column layouts.

For horizontal scrolling, set the horizontal prop to true:

<FlatList
 data={DATA}
 renderItem={renderItem}
 horizontal={true}
 showsHorizontalScrollIndicator={false}
/>

The inverted prop reverses scroll direction, which can be useful for chat interfaces or other specialized UIs where content should flow from bottom to top. These patterns are essential when building cross-platform applications that need consistent UI across iOS and Android.

Common Questions About FlatList

Why isn't my FlatList re-rendering when data changes?

FlatList implements PureComponent, so it won't re-render if props remain shallowly equal. Use the extraData prop to signal FlatList when external state changes, especially for selection states or external data dependencies.

How do I handle items with different heights?

For items with variable heights, avoid getItemLayout and let FlatList measure dynamically. Consider estimating average item height to reduce measurement overhead. For complex dynamic layouts, profile performance and consider alternative approaches.

What's causing blank areas during fast scrolling?

Blank areas appear when scrolling faster than the render rate. Increase maxToRenderPerBatch, decrease updateCellsBatchingPeriod, or increase windowSize. Also ensure item components are lightweight.

When should I use SectionList instead of FlatList?

Use SectionList when you need to group items into sections with headers. SectionList supports the same performance optimizations as FlatList but adds section-specific props and rendering.

Summary and Best Practices

FlatList is React Native's essential component for efficient list rendering. Mastery involves understanding both its capabilities and its optimization requirements.

Key takeaways:

  • Always provide unique keys through keyExtractor for proper reconciliation
  • Use extraData to trigger re-renders when external state changes
  • Optimize item components with React.memo() and avoid inline functions
  • Consider getItemLayout for lists with fixed-height items
  • Tune performance props based on your specific use case and data size
  • Keep item components lightweight for best scrolling performance

With these techniques, FlatList can handle lists of any size while maintaining the smooth, responsive experience users expect from native mobile applications. For teams building cross-platform applications, mastering FlatList is essential for delivering exceptional user experiences. When implementing AI-driven user interfaces, efficient list rendering becomes critical for displaying dynamic content streams from machine learning models.

Our web development team can help you implement these optimization strategies across your entire application stack, whether you're building mobile-first experiences or comprehensive digital solutions.

Ready to Build High-Performance React Native Apps?

Our team specializes in creating performant mobile applications with React Native and modern web technologies.