FlatList — React Native 的主要组件,用于通过元素虚拟化显示高性能列表。与 ScrollView 不同,FlatList 只渲染屏幕的可见元素,节省内存和处理器。该组件支持水平和垂直滚动、下拉刷新和无限加载。有关列表架构的更多信息,请参阅 Meta 文档。
要点
FlatList — React Native 组件,实现了带有高性能渲染大量数据的虚拟化列表。该组件基于 VirtualizedList 构建,提供声明式 API 用于创建任意复杂度的平面列表。
FlatList 出现在 React Native 0.43 中,作为已废弃的 ListView 的替代品。根据 Meta(2026)的数据,FlatList 用于 85% 的与列表打交道的 React Native 应用程序。该组件支持所有常见场景:联系人、新闻推送、产品目录、聊天。
在 FlatList 出现之前,开发人员使用 ListView,它需要手动配置单元格重用。FlatList 通过引入类似于 Android 中的 RecyclerView(2014)和 iOS 中的 UICollectionView(2012)的窗口渲染来自动化这一过程。在现代项目中,FlatList 是所有列表的事实标准。
FlatList 虚拟化 — 组件只渲染位于屏幕可见区域中的元素,加上每侧的一个小缓冲区的机制。其余元素不会在 DOM 中创建,从而节省内存并加速渲染。
滚动时,FlatList 重用已经创建的 View 单元格,替换其中的数据。这防止为包含 10,000 个元素的列表创建成千上万个 View。默认缓冲区大小是可见区域上方和下方各 10 个元素,但可以通过 windowSize 进行配置。
| 参数 | 默认值 | 描述 |
|---|---|---|
| windowSize | 21 | 用于渲染的页数(1 页 = 屏幕高度) |
| initialNumToRender | 10 | 首次渲染时的元素数量 |
| maxToRenderPerBatch | 10 | 每批渲染的最大元素数 |
| removeClippedSubviews | false | 从层次结构中移除屏幕外的 View |
这些参数的优化配置可以在滚动流畅度和内存消耗之间取得平衡。对于包含大元素的列表,建议将 windowSize 减小到 5-7。
FlatList API 包含一组用于配置列表外观和行为的属性。两个必需属性 — data(数据数组)和 renderItem(元素渲染函数)。keyExtractor 通过为每个元素提供唯一键来提高性能。
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
const App = () => {
const data = Array.from({ length: 100 }, (_, i) => ({
id: i.toString(),
title: `Item #${i + 1}`,
}));
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
};ItemSeparatorComponent 在元素之间添加分隔符,ListHeaderComponent 和 ListFooterComponent — 列表的页眉和页脚。这允许无需额外包装即可创建复杂布局。
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
separator: {
height: 1,
backgroundColor: '#ccc',
},
});FlatList 优化对于包含成百上千个元素的应用程序至关重要。如果没有正确配置,列表在滚动时可能会变慢,消耗过多内存,并在弱设备上导致崩溃。
第一条规则 — 使用带有唯一且稳定标识符的 keyExtractor。使用索引作为键会导致不正确的单元格重用和状态错误。第二条 — 将 renderItem 包装在 useCallback 中,并对元素组件使用 React.memo。
如果所有元素具有相同的高度,getItemLayout 允许 FlatList 无需测量组件即可计算滚动位置。这提供了显著的性能提升,特别是在滚动到特定索引时。
const ITEM_HEIGHT = 80;
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<FlatList
data={data}
getItemLayout={getItemLayout}
renderItem={renderItem}
/FlatList>对数据使用 useMemo 可防止不必要的重新渲染。如果数据来自 API,请一次性转换并缓存。对元素组件使用 React.memo 以避免渲染未更改的元素。
水平 FlatList 通过添加 horizontal={true} 属性创建。列表将滚动方向改为 X 轴,方便用于产品轮播、图片库和水平菜单。
在水平模式下,正确配置 snapToInterval 和 snapToAlignment 以实现步进滚动非常重要,就像原生轮播一样。组件自动处理惯性和手指释放,停在最近的元素上。
<FlatList
horizontal
data={images}
renderItem={renderItem}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
snapToInterval={CARD_WIDTH + GAP}
snapToAlignment="start"
decelerationRate="fast"
pagingEnabled
onViewableItemsChanged={onViewableItemsChanged}
/>onViewableItemsChanged — 当可见元素发生变化时调用的回调。用于分析、图片懒加载以及仅对可见卡片激活视频。
下拉刷新在 FlatList 中通过 refreshing 和 onRefresh 属性实现,它们与加载状态协同工作。当列表被下拉时,调用 onRefresh,refreshing 标志阻止重复调用。
无限加载通过 onEndReached 配置 — 当接近列表末尾时触发的回调。onEndReachedThreshold 确定在末尾之前多少个元素触发事件。分页通常使用基于游标的方法。
const ListWithPagination = () => {
const [data, setData] = React.useState([]);
const [page, setPage] = React.useState(1);
const [refreshing, setRefreshing] = React.useState(false);
const loadMore = React.useCallback(async () => {
const newData = await fetchPage(page);
setData(prev => [...prev, ...newData]);
setPage(p => p + 1);
}, [page]);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshing={refreshing}
onRefresh={loadMore}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>
);
};重要:onEndReached 可能被多次调用。添加 isLoading 标志以阻止在上一个请求完成之前的重复请求。在 ListFooterComponent 中使用 ActivityIndicator 来指示加载状态。
常见问题
FlatList 使用虚拟化 — 只渲染可见元素,在大数据量时节省内存。ScrollView 立即渲染所有子元素,仅适用于最多 20-30 个元素的小列表。FlatList 对于 100+ 个元素是最优的。
闪烁在 data 数组引用更改时发生。使用 extraData,将依赖项传递到那里,或将 renderItem 包装在 React.memo 中。为了完全控制,应用 useMemo 来稳定数据引用。
FlatList 由于手势冲突不设计为嵌套在 ScrollView 中。解决方案:使用带有 nestedScrollEnabled 的 FlatList(Android)、用于分节的 SectionList,或通过 ListHeaderComponent 将外部滚动移动到 FlatList。
在 renderItem 内部使用 Animated API,基于索引添加延迟。滚动时应用 onViewableItemsChanged 触发动画。react-native-reanimated 和 react-native-lottie 库简化了复杂出现动画的创建。
VirtualizedList — FlatList 和 SectionList 所基于的基础虚拟化组件。FlatList 是 VirtualizedList 的包装器,为平面列表提供了简化的 API。VirtualizedList 提供更低级别的控制,但很少直接使用。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。