If you’ve landed here looking for a react native listview example, I've got some important news for you: the ListView component is deprecated. For any modern React Native project, you should skip it entirely and use FlatList or SectionList instead. They offer way better performance and are much easier to work with.
Let's take a quick look at why the entire community moved on.
Why Modern Apps Abandoned ListView for FlatList
Back when React Native first came out around 2015, ListView was all we had for rendering scrollable lists. It got the job done, but it had a massive, hidden flaw that caused endless headaches as apps became more complex.

The Core Performance Problem
The fundamental issue with ListView was how it handled memory. It would render every single item in your data source all at once and keep them in memory, even if they weren't visible on the screen. For a tiny list with ten items, you might not notice. But for a list with hundreds or thousands of rows—think a social media feed or a product catalog—this approach was a performance disaster.
I still remember the pain of trying to optimize ListView on older Android devices. Apps would get sluggish, the UI would freeze, and out-of-memory crashes were a constant struggle. It wasn't just a small bug; it was a fundamental barrier to building scalable, production-ready apps.
The core issue with the old
ListViewwas simple: it had no concept of virtualization. It treated a list of 1,000 items the same way it treated a list of 10, creating every view and keeping it in memory, which inevitably led to performance collapse.
By 2017, this problem had become too big to ignore. For lists with over 1,000 items, we saw memory usage spike by as much as 500%. This crisis led the React Native team to officially deprecate ListView in version 0.60 (released July 3, 2019), pointing everyone toward its much-improved successors. You can dig into the history by checking out the official documentation on the deprecation.
The Rise of Virtualized Lists
This is where FlatList changed the game. It was built from the ground up to solve the exact performance nightmare ListView created. FlatList uses a clever technique called virtualization.
Instead of rendering everything at once, it only renders the items currently visible in the viewport (plus a few on either side to make scrolling feel smooth). As you scroll, FlatList recycles the views—unmounting components that move off-screen and mounting new ones that come into view. This keeps memory usage low and consistent, ensuring a buttery-smooth UI even with massive datasets.
To put it plainly, FlatList is just smarter. Here's a quick breakdown of the key differences that make it the obvious choice today.
ListView vs FlatList Key Differences
| Feature | ListView (Deprecated) | FlatList (Modern) |
|---|---|---|
| Memory Usage | High. Renders all items at once, causing crashes with long lists. | Low. Only renders visible items, keeping memory flat. |
| Performance | Poor for long lists. UI can become slow and unresponsive. | Excellent. Smooth scrolling even with thousands of items. |
| API | Complex. Required a dataSource and rowHasChanged logic. | Simple. Accepts a plain data array and a renderItem prop. |
| Features | Basic. Lacked built-in pull-to-refresh or infinite scroll helpers. | Rich. Built-in support for pull-to-refresh, headers, footers, and separators. |
| Maintenance | None. It is no longer maintained or recommended by the React Native team. | Actively maintained and the official recommendation for all lists. |
In short, FlatList is not just an update; it's a complete paradigm shift that fixed the most critical performance issues of its predecessor.
Building Your First High-Performance FlatList
Enough with the theory—let's get our hands dirty. The best way to really understand why FlatList is the go-to choice over the old ListView is to build a modern react native listview example from the ground up. We’ll tackle a classic UI pattern: a vertical list of products, complete with a name, price, and image for each.
This walkthrough won't just give you a copy-and-paste-ready component. More importantly, it will show you how the three most critical props—data, renderItem, and keyExtractor—work together. Once you get these, you're 90% of the way there.
The Core Code Structure
First things first, here’s the complete component. This code sets up a basic FlatList that renders an array of product data. It’s clean, efficient, and serves as the foundation for just about any list you'll ever need to build in React Native.
import React from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text, Image } from 'react-native';
const PRODUCT_DATA = [
{ id: '1', title: 'Espresso Machine', price: '$199.99', image: 'path/to/image1.jpg' },
{ id: '2', title: 'Pour-Over Coffee Maker', price: '$34.99', image: 'path/to/image2.jpg' },
{ id: '3', title: 'Premium Coffee Beans', price: '$22.50', image: 'path/to/image3.jpg' },
// …add more product items here
];
const ProductItem = ({ title, price, image }) => (
<Image source={{ uri: image }} style={styles.image} />
{title}
{price}
);
const ProductList = () => {
const renderProductItem = ({ item }) => (
);
return (
<FlatList
data={PRODUCT_DATA}
renderItem={renderProductItem}
keyExtractor={item => item.id}
/>
);
};
const styles = StyleSheet.create({
// …your styles would go here
});
export default ProductList;
It might look deceptively simple, but this structure is incredibly powerful. Let's pull back the curtain and see what’s really going on with those three core props.
Understanding the Essential Props
To truly master FlatList, you have to get comfortable with its main props. Think of them as the three pillars that hold up your list's performance and structure.
data: This one is the most straightforward. It’s the array of information you want to display. In our code,PRODUCT_DATAis an array of objects, with each object representing a single product.renderItem: This is a function that tellsFlatListexactly how to draw a single item from your data array. It’s called for each item and receives an object containing theitemitself (and itsindex). Your job is to return a React component from it. We defined a separateProductItemcomponent to keep our code clean and reusable.keyExtractor: Here’s the secret sauce for performance. This function’s job is to giveFlatLista unique ID for every single item in your list. React uses these keys under the hood to efficiently track items, which is absolutely critical for optimizing renders when data changes.
Always use a stable, unique string for the
keyExtractor, like a database ID. A common mistake I see is using the item's index as a key, but that can cause weird bugs and performance hits when you add, remove, or reorder items in the list.
Without a solid keyExtractor, React Native gets confused about what changed and might have to re-render the entire list just to be safe. By giving it a unique id for each product, we provide a shortcut that lets it surgically update, add, or remove individual rows without touching anything else.
This simple setup is the modern, performant replacement for any old react native listview example you might find. It's easier to reason about and has become the standard for all new app development.
If you're ready to explore more advanced features like pull-to-refresh or infinite scrolling, you can learn how to use React Native FlatList in our more in-depth guide. By starting with this solid foundation, you’re well on your way to building fast, scalable mobile apps.
Mastering Essential FlatList Props for Smooth Scrolling
Getting a basic list on the screen is one thing, but making it scroll flawlessly with thousands of items is another story. This is where we go beyond a simple <FlatList> and really start tuning it for performance. Honestly, getting these props right is the main reason we moved on from the old react native listview example in the first place.
Let's dig into the props that will give you that buttery-smooth experience users expect.
Fine-Tuning Your Initial Render
The first prop I always look at is initialNumToRender. This tells FlatList exactly how many items to render when the component first mounts, right before a user even lays a finger on the screen.
It’s a balancing act. If you set this number too low, your users might see a brief flash of blank space as they start to scroll. If you set it too high, you’re rendering too much upfront and losing some of the performance benefits you were trying to gain.
So, how do you find the sweet spot? A good rule of thumb I've used on many projects is to render just enough items to fill the screen, plus one or two extras for a small buffer.
For example, say your phone's screen is 800 pixels tall and your list items are each 70 pixels high. That means you can fit about 11.4 items in the viewport. In that case, I'd start by setting initialNumToRender to 12 or 13. This ensures the screen feels full and responsive from the very beginning.
Pre-Calculating Item Layouts for a Speed Boost
Another incredibly powerful prop is getItemLayout, especially if all your list items have the same, fixed height. By implementing this function, you give FlatList a shortcut, letting it skip the expensive process of measuring every single item dynamically.
You're essentially giving it a map, telling it exactly where each item will be placed before it even renders. This is a huge performance win.
const ITEM_HEIGHT = 70; // Your fixed item height
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<FlatList
// …other props
getItemLayout={getItemLayout}
/>
Reclaiming Memory from Off-Screen Items
Finally, there's removeClippedSubviews. When you set this prop to true, FlatList will automatically detach views that have been scrolled far off-screen. This directly tackles one of the biggest memory problems of the original ListView component, which insisted on keeping everything in memory at all times.
A word of caution:
removeClippedSubviewshas a history of being a bit buggy. I’d advise using it carefully and testing it thoroughly on both platforms. It can sometimes cause content to disappear unexpectedly, particularly with complex list items. It’s often best reserved for simple lists where you’re aggressively trying to optimize memory usage.
Choosing the right list component is the first step. This simple flowchart can help guide your decision based on your data structure.

As the chart shows, if your data is a simple flat array, FlatList is your go-to. For data that’s already grouped into sections, you’ll want to reach for SectionList.
The impact of these props isn't just theoretical. A well-tuned FlatList using initialNumToRender can easily hit a 150ms load time while maintaining a silky 60fps scroll. In some tests, removeClippedSubviews has been shown to cut re-renders by 82%, while getItemLayout can boost scroll performance by a staggering 45% on lists with as many as 20,000 items.
Using these props correctly is a cornerstone of building professional, high-quality mobile apps. If you want to dive even deeper, check out our guide on how to improve the performance of a React Native app.
Handling Grouped Data and Headers with SectionList
While FlatList is a workhorse for simple, linear lists, many real-world apps need more structure. Think of a contact list grouped by letter, a settings menu with distinct categories, or a restaurant menu broken down by "Appetizers," "Main Courses," and "Desserts." For these jobs, a flat list just won't cut it. This is where SectionList shines.

SectionList is a high-performance component built specifically for rendering grouped or sectioned data. It's engineered on the same virtualization principles as FlatList, so you get all the performance benefits while being able to add headers for your data groups. It’s the natural next step when you outgrow what a basic list can do.
Structuring Your Data for Sections
The biggest change you'll encounter when moving to SectionList is how your data needs to be shaped. Instead of a simple array of items, SectionList expects an array of objects, where each object represents a full section.
Each section object needs two key properties: a title (or some other identifier for the header) and a data array holding the items for that specific section.
Here’s a quick look at that restaurant menu example. It's a perfect use case for SectionList.
const MENU_DATA = [
{
title: 'Appetizers',
data: ['Bruschetta', 'Garlic Bread', 'Calamari'],
},
{
title: 'Main Courses',
data: ['Spaghetti Carbonara', 'Margherita Pizza', 'Grilled Salmon'],
},
{
title: 'Desserts',
data: ['Tiramisu', 'Panna Cotta', 'Gelato'],
},
];
This clear, nested structure is exactly what SectionList needs to render both your headers and the items within each group.
Key Props for Building a SectionList
Implementing a SectionList will feel very familiar if you've used FlatList, but there are a few important differences in the props. The most obvious one is that you'll use sections instead of data.
sections: This is where you pass your structured data, like theMENU_DATAarray we just created.renderItem: This prop works exactly like it does inFlatList. It’s a function that gets an item from a section'sdataarray and returns the component for that row.renderSectionHeader: This is the new, essential prop. It's a function that receives information about the entire section (including itstitle) and must return a component to serve as the header.keyExtractor: Just as crucial as withFlatList, this prop is vital for performance. It needs to return a unique string key for each individual item (not the section) so React can efficiently manage re-renders.
Let’s see how these props come together in a basic implementation:
import { SectionList, Text, View, StyleSheet } from 'react-native';
// … assuming MENU_DATA is defined above
const Menu = () => (
<SectionList
sections={MENU_DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
{item}
)}
renderSectionHeader={({ section: { title } }) => (
{title}
)}
/>
);
Choosing between
FlatListandSectionListis a simple but important architectural decision. If your data source is a flat array, stick withFlatList. The moment you need to display that data in distinct, titled groups, it’s time to switch toSectionList.
Knowing when to make this move is a key part of building organized, user-friendly interfaces that can handle complex data displays with ease.
When FlatList Isn't Enough: Pushing Lists to the Extreme
Even with every optimization trick in the book, a FlatList has its breaking point. It's the go-to replacement for any old react native listview example, but there are some edge cases where even its clever virtualization can’t keep up. We're talking about really demanding apps—think a social feed with tens of thousands of items, each with different heights, media, and interactive components.

When you push FlatList this hard, the signs are obvious. You'll see frame drops during a fast scroll, stuttering animations, or weird glitches when you try to programmatically jump to an item. If you’re seeing this, you’ve likely hit the architectural ceiling. For these high-performance scenarios, it's time to look at some specialized third-party libraries.
What True View Recycling Looks Like
This is where libraries like react-native-big-list completely change the game. Their secret sauce is a true view recycling system, similar to what native Android developers get with RecyclerView. Instead of just unmounting components that scroll off-screen, these libraries maintain a small pool of views. As a view scrolls out of sight, it’s put back in the pool, and as a new item scrolls into view, an old view is grabbed, and its data is simply rebound.
This approach massively cuts down on creating new objects and triggering garbage collection, which are often the culprits behind UI jank.
The performance difference is night and day. On a list with 50,000 complex items, FlatList might start to struggle, dipping to 30–45fps. In contrast, benchmarks for react-native-big-list show it handling that same list at a buttery-smooth 120fps on an iPhone 14. It's built from the ground up to solve common FlatList headaches like empty frame mounts and unreliable scrollToIndex behavior.
Pulling in another dependency is a big decision. But when your app's entire user experience hinges on a massive, interactive list, the performance boost from a specialized library can absolutely justify the added complexity. It's a classic trade-off for a much better user experience.
So, When Is a Third-Party Library Worth the Trouble?
Moving away from a core component like FlatList shouldn't be your first move. It’s a powerful tool for a reason. But you should have a more specialized library in your back pocket for certain situations.
Consider making the switch if you're facing one of these challenges:
- Infinite Feeds with Heavy Items: Your app is built around a social-style feed where users can scroll endlessly through items packed with mixed media, text, and interactive buttons.
- Large-Scale, Variable-Height Content: Your list items have wildly different heights that are impossible to predict, making the
getItemLayoutoptimization useless. - Strict Performance Requirements: Your app must maintain 60+ fps during scrolls, even on older or less powerful devices.
For most apps, FlatList is more than enough. But for developers working on projects that operate at a massive scale, knowing these alternatives exist is a critical piece of the puzzle. Of course, no list component can perform well without a solid foundation. Optimizing your entire build with tools like Hermes is just as important. If you want to squeeze every bit of performance out of your app, our guide on how to set up Hermes in React Native is a great place to start.
Even after getting your hands dirty with FlatList and SectionList, a few questions almost always come up. Let's run through the common ones I hear from developers to iron out any final wrinkles.
Can I Still Use ListView in My 2026 React Native Project?
Absolutely not. That’s the short and non-negotiable answer. ListView was officially put out to pasture back in 2019 with React Native version 0.60. It's notorious for performance issues because it tries to render every single item in your list at once, which eats up memory and grinds your app to a halt.
If you try to use it today, modern tooling will light up with warnings. More importantly, you're signing up for a sluggish app that's prone to crashes, especially on lower-end devices. For any new development, FlatList or SectionList are your only real options.
Sticking with the old
ListViewis like trying to build a modern car with a steam engine. Sure, it might chug along for a bit, but it's wildly inefficient, outdated, and can't possibly keep up with the alternatives.
What Is the Most Important Prop for FlatList Performance?
If I had to pick just one prop that makes or breaks performance, it's keyExtractor. This little function is the most critical piece of the puzzle for keeping your list snappy during updates. It gives React a stable, unique ID for every single item.
React's whole reconciliation process hinges on these keys to figure out what's changed, what's new, and what's gone. If you don't provide a good keyExtractor, React gets confused and might just re-render the entire list from scratch—completely wiping out the performance gains from FlatList's virtualization. Always use something truly unique and stable, like a database ID.
When Should I Use SectionList Instead of FlatList?
This one really just boils down to the shape of your data.
FlatListis your go-to for a simple, linear array of items. It's perfect for things like a social media feed, a product catalog, or any long, continuous scroll of similar content.SectionListis what you'll reach for when your data is naturally grouped. The classic example is a phone's contact list grouped by the first letter of the name. Other great use cases include a settings screen with different categories or a restaurant menu broken down by appetizers, main courses, and desserts.
How Do I Handle Infinite Scrolling with FlatList?
FlatList makes infinite scrolling pretty easy to implement using two main props: onEndReached and onEndReachedThreshold.
The onEndReached prop is just a function that gets called when the user scrolls close to the bottom of your current list. This is where you'll put your logic to fetch the next "page" of data from your API and add it to your state.
The onEndReachedThreshold prop tells the list how close to the bottom the user needs to be before firing that function. It’s a number based on screen lengths, so a value like 0.5 means the onEndReached function will trigger when the user is half a screen length away from the end. This is a great way to start loading new data before the user ever hits the bottom, creating a seamless experience.
At React Native Coders, we're all about providing practical, up-to-date guides to help you build fantastic mobile apps. We cover everything from deep dives on performance to the latest trends in the ecosystem. You can find more of our expert insights and strategies at https://reactnativecoders.com.





















Add Comment