FlatList:是什么,React Native 中的 API 和优化

作者: IT Sectr 发布日期: 2026-07-05 阅读时间: 10 分钟

FlatList — React Native 的主要组件,用于通过元素虚拟化显示高性能列表。与 ScrollView 不同,FlatList 只渲染屏幕的可见元素,节省内存和处理器。该组件支持水平和垂直滚动、下拉刷新和无限加载。有关列表架构的更多信息,请参阅 Meta 文档

要点

  • FlatList — 虚拟化列表组件,只渲染可见元素并在滚动时重用它们
  • 性能通过窗口渲染(windowing)实现 — 屏幕外的元素不会被创建
  • API包括 renderItem、keyExtractor、ItemSeparatorComponent、ListHeaderComponent 和 ListFooterComponent
  • 水平列表通过 horizontal 标志配置,将滚动方向改为 X 轴
  • 优化需要正确配置 keyExtractor、用于数据的 useMemo 和用于固定尺寸的 getItemLayout

什么是 FlatList?

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 虚拟化如何工作

FlatList 虚拟化 — 组件只渲染位于屏幕可见区域中的元素,加上每侧的一个小缓冲区的机制。其余元素不会在 DOM 中创建,从而节省内存并加速渲染。

滚动时,FlatList 重用已经创建的 View 单元格,替换其中的数据。这防止为包含 10,000 个元素的列表创建成千上万个 View。默认缓冲区大小是可见区域上方和下方各 10 个元素,但可以通过 windowSize 进行配置。

参数默认值描述
windowSize21用于渲染的页数(1 页 = 屏幕高度)
initialNumToRender10首次渲染时的元素数量
maxToRenderPerBatch10每批渲染的最大元素数
removeClippedSubviewsfalse从层次结构中移除屏幕外的 View

这些参数的优化配置可以在滚动流畅度和内存消耗之间取得平衡。对于包含大元素的列表,建议将 windowSize 减小到 5-7。

FlatList 的 API 和主要属性

FlatList API 包含一组用于配置列表外观和行为的属性。两个必需属性 — data(数据数组)和 renderItem(元素渲染函数)。keyExtractor 通过为每个元素提供唯一键来提高性能。

js
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 在元素之间添加分隔符,ListHeaderComponentListFooterComponent — 列表的页眉和页脚。这允许无需额外包装即可创建复杂布局。

js
const styles = StyleSheet.create({
  item: {
    padding: 16,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  separator: {
    height: 1,
    backgroundColor: '#ccc',
  },
});

优化 FlatList 性能

FlatList 优化对于包含成百上千个元素的应用程序至关重要。如果没有正确配置,列表在滚动时可能会变慢,消耗过多内存,并在弱设备上导致崩溃。

第一条规则 — 使用带有唯一且稳定标识符的 keyExtractor。使用索引作为键会导致不正确的单元格重用和状态错误。第二条 — 将 renderItem 包装在 useCallback 中,并对元素组件使用 React.memo。

针对固定高度的 getItemLayout

如果所有元素具有相同的高度,getItemLayout 允许 FlatList 无需测量组件即可计算滚动位置。这提供了显著的性能提升,特别是在滚动到特定索引时。

js
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 轴,方便用于产品轮播、图片库和水平菜单。

在水平模式下,正确配置 snapToIntervalsnapToAlignment 以实现步进滚动非常重要,就像原生轮播一样。组件自动处理惯性和手指释放,停在最近的元素上。

js
<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 确定在末尾之前多少个元素触发事件。分页通常使用基于游标的方法。

js
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 有何不同?

FlatList 使用虚拟化 — 只渲染可见元素,在大数据量时节省内存。ScrollView 立即渲染所有子元素,仅适用于最多 20-30 个元素的小列表。FlatList 对于 100+ 个元素是最优的。

如何在更新 FlatList 数据时修复闪烁?

闪烁在 data 数组引用更改时发生。使用 extraData,将依赖项传递到那里,或将 renderItem 包装在 React.memo 中。为了完全控制,应用 useMemo 来稳定数据引用。

为什么 FlatList 在另一个滚动视图中无法滚动?

FlatList 由于手势冲突不设计为嵌套在 ScrollView 中。解决方案:使用带有 nestedScrollEnabled 的 FlatList(Android)、用于分节的 SectionList,或通过 ListHeaderComponent 将外部滚动移动到 FlatList。

如何为 FlatList 元素的出现添加动画?

在 renderItem 内部使用 Animated API,基于索引添加延迟。滚动时应用 onViewableItemsChanged 触发动画。react-native-reanimated 和 react-native-lottie 库简化了复杂出现动画的创建。

什么是 VirtualizedList 及其与 FlatList 的关系?

VirtualizedList — FlatList 和 SectionList 所基于的基础虚拟化组件。FlatList 是 VirtualizedList 的包装器,为平面列表提供了简化的 API。VirtualizedList 提供更低级别的控制,但很少直接使用。

总结

  • FlatList — React Native 的主要组件,用于具有自动虚拟化和单元格重用的高性能列表
  • 虚拟化通过 windowSize 和 initialNumToRender 仅渲染可见元素,在大型数据集上节省内存
  • 必需属性:data、renderItem 和 keyExtractor — 确保列表正常运行
  • getItemLayout 加速固定高度元素的滚动,消除动态测量
  • 水平列表和轮播通过 horizontal 和 snapToInterval 配置以实现步进滚动
  • 下拉刷新和 onEndReached 实现无限加载,并防止重复调用
  • React.memo和 useCallback 是 renderItem 必需的 — 没有它们,每次滚动都会导致所有元素重新渲染

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读