进阶 reactnative.dev 2026-10-11 06:04:21 · 23 阅读

第41章 FlatList · React Native

版本:0.77FlatList用于渲染基础扁平列表的高性能组件,支持以下常用功能: - 完全跨平台。 - 可选水平布局模式。 - 可配置的可见性回调。 - 支持头部组件。 - 支持底部组件。 - 支持分隔线。 - 下拉刷新。 - 滚动加载。 - 支持 ScrollToIndex。 - 支持多列布局。 如果需要分组列表,请使用 。 示例​ TypeScriptJavaScript 要渲染多列列表,可以使用 numColumns 属性。相比 flexWrap 布局,这种方式可以避免与列表项高度逻辑产生冲突。 下面是一个更复杂的、支持选中操作的示例。 通过给 FlatList 传入 extraData={selectedId},可以确保状态变化时 FlatList 自身会重新渲染。如果不设置这个属性,FlatList 将不知道需要重新渲染列表项——因为它是 PureComponent,属性浅比较不会检测到任何变化。 keyExtractor 用于告诉列表使用 id 作为 React key,而不是默认的 key 属性。 TypeScriptJavaScript FlatList 是对 的便捷封装,因此会继承其属性(以及 的属性),此处不再一一列出,但有以下注意事项: - 当内容滚出渲染窗口时,内部状态不会被保留。请确保所有数据都保存在列表项数据中,或存放在 Flux、Redux、Relay 等外部状态管理中。 - FlatList 是 PureComponent,即属性浅比较相等时不会重新渲染。请确保 renderItem 函数依赖的所有数据都以属性形式传入(如 extraData),且更新后不满足 === 相等,否则界面可能不会随数据变化而更新。这包括 data 属性和父组件的 state。 - 为了控制内存占用并保证滚动流畅,内容是在屏幕外异步渲染的。这意味着滚动速度可能快于渲染速度,从而短暂看到空白内容。这是一种权衡,可以根据应用需求进行调整,我们也在持续改进。 - 默认情况下,列表会在每个列表项上查找 key 属性并将其用作 React key。你也可以通过自定义 keyExtractor 属性来替代。 参考文档 属性​ VirtualizedList 属性​ 继承 VirtualizedList 的所有属性。 必填 renderItem​ React TSXrenderItem({
item: ItemT,
index: number,
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
}
}): JSX.Element;
接收数据中的项并将其渲染到列表中。 如需附加元数据(如 index),此处可提供。它还包含更通用的 separators.updateProps 函数,允许你设置任意 props 来修改前导或尾部分隔符的渲染方式,以防更常用的高亮和取消高亮(它们会设置 highlighted: boolean 属性)无法满足你的使用场景。 类型function item (Object): 被渲染的数据项。 index (number): 该数据项在数据数组中的索引。 separators (Object) highlight (Function) unhighlight (Function) updateProps (Function) select (enum('leading', 'trailing')) newProps (Object) 使用示例: React TSX ItemSeparatorComponent={
Platform.OS !== 'android' &&
(({highlighted}) => (
style={[style.separator, highlighted && {marginLeft: 0}]}
/>
))
}
data={[{title: 'Title Text', key: 'item1'}]}
renderItem={({item, index, separators}) => (
key={item.key}
onPress={() => this._onPress(item)}
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}>

{item.title}


)}
/>
必需数据 待渲染的项目数组(或类数组列表)。如直接使用 VirtualizedList,也可使用其他数据类型。 类型:ArrayLike ItemSeparatorComponent 渲染在每个项目之间,但不出现在列表顶部或底部。默认会提供 highlighted 和 leadingItem 属性。renderItem 提供的 separators.highlight/unhighlight 方法会更新 highlighted 属性,你也可以通过 separators.updateProps 添加自定义属性。该组件可以是 React 组件(如 SomeComponent),也可以是 React 元素(如 )。 类型:component、function、element ListEmptyComponent 列表为空时渲染。可以是 React 组件(如 SomeComponent),也可以是 React 元素(如 )。 类型:component、element ListFooterComponent 渲染在所有项目的底部。可以是 React 组件(如 SomeComponent),也可以是 React 元素(如 )。 类型:component、element ListFooterComponentStyle ListFooterComponent 内部 View 的样式。 类型:View Style ListHeaderComponent 渲染在所有项目的顶部。可以是 React 组件(如 SomeComponent),也可以是 React 元素(如 )。 类型:component、element ListHeaderComponentStyle ListHeaderComponent 内部 View 的样式。 类型:View Style columnWrapperStyle 当 numColumns > 1 时,生成的多列行的可选自定义样式。 类型:View Style extraData 标记属性,用于告知列表重新渲染(因为该组件实现了 PureComponent)。如果 renderItem、Header、Footer 等函数依赖于 data 属性之外的内容,请将该内容放在这里,并按不可变方式处理。 类型:any getItemLayout React TSX(data, index) => {length: number, offset: number, index: number}
getItemLayout 是一个可选的优化功能,如果你预先知道项目的大小(高度或宽度),它允许跳过对动态内容的测量。当项目大小固定时,getItemLayout 效率很高,例如: React TSX getItemLayout={(data, index) => (
{length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
)}
设置 getItemLayout 能为包含几百个元素的列表带来显著的性能提升。注意,如果指定了 ItemSeparatorComponent,计算偏移量时要记得把分隔符的长度(高度或宽度)算进去。 类型:function horizontal​ 设为 true 时,列表项横向排列,而不是纵向堆叠。 类型:boolean initialNumToRender​ 首批渲染的元素数量。这个值够填满屏幕即可,不要设太大。注意,为了提升“回到顶部”操作的性能体验,这些元素在窗口化渲染中永远不会被卸载。 类型:number 默认值:10 initialScrollIndex​ 不从第一个元素开始,而是从 initialScrollIndex 指定的位置开始渲染。这会禁用“回到顶部”的优化(该优化会始终保持前 initialNumToRender 个元素处于渲染状态),并立即从指定的初始索引开始渲染元素。需要实现 getItemLayout。 类型:number inverted​ 反转滚动方向。通过 -1 的 scale 变换实现。 类型:boolean keyExtractor​ React TSX(item: ItemT, index: number) => string;
用于为指定索引处的元素提取唯一 key。key 用于缓存,也作为 React 的 key 来追踪元素的重新排序。默认的提取逻辑会依次检查 item.key、item.id,最后退回到使用索引,与 React 的做法一致。 类型:function numColumns​ 多列布局只能在 horizontal={false} 时使用,排列方式类似 flexWrap 的折行效果。所有元素必须高度一致,不支持瀑布流布局。 类型:number onRefresh​ React TSX() => void;
若提供该参数,系统将自动添加标准的 RefreshControl,以支持“下拉刷新”功能。请务必正确设置 refreshing 属性。 类型 function onViewableItemsChanged 当行的可见性状态发生变化时触发,判定标准由 viewabilityConfig 属性定义。 类型 (callback: {changed: ViewToken[], viewableItems: ViewToken[]} => void; progressViewOffset 若需确保加载指示器正确显示,请设置此偏移量。 类型 number refreshing 在等待刷新获取新数据期间,将此值设为 true。 类型 boolean removeClippedSubviews 该属性可能提升长列表的滚动性能。在 Android 平台上,默认值为 true。 注意:在某些情况下可能存在 bug(如内容缺失),使用需谨慎。 类型 boolean viewabilityConfig 关于 Flow 类型定义及更多文档,请参阅 ViewabilityHelper.js。 类型 ViewabilityConfig viewabilityConfig 接收一个 ViewabilityConfig 对象,该对象包含以下属性: 属性 类型 minimumViewTime number viewAreaCoveragePercentThreshold number itemVisiblePercentThreshold number waitForInteraction boolean viewAreaCoveragePercentThreshold 和 itemVisiblePercentThreshold 中至少需要设置一项。为避免以下错误,须在构造器中完成该配置(参考): 错误:不支持动态修改 viewabilityConfig
React TSX 构造器 (props) {
super(props)

this.viewabilityConfig = {
waitForInteraction: true,
viewAreaCoveragePercentThreshold: 95
}
}
React TSX viewabilityConfig={this.viewabilityConfig}
...
minimumViewTime​ 项目在被判定为“可见”并触发可见性回调前,必须实际处于可见状态的最短时间(毫秒)。数值越高,表示快速滚动时若不停顿,该部分内容将不会被标记为可见。 viewAreaCoveragePercentThreshold​ 部分遮挡的项目要被计为“可见”,其必须覆盖视口的百分比,取值范围 0-100。完全可见的项目始终被视为可见。值为 0 意味着视口中只要有 1 像素可见即算可见;值为 100 意味着项目必须完全可见,或完全覆盖整个视口才计为可见。 itemVisiblePercentThreshold​ 类似于 viewAreaCoveragePercentThreshold,但计算的是项目自身可见部分的百分比,而非其覆盖可见区域的比例。 waitForInteraction​ 在用户滚动或调用 recordInteraction 之前,任何内容都不被视为可见。 viewabilityConfigCallbackPairs​ ViewabilityConfig/onViewableItemsChanged 的配对列表。当对应的 ViewabilityConfig 条件满足时,将调用特定的 onViewableItemsChanged。请参阅 ViewabilityHelper.js 了解流类型及更多文档。 Typearray of ViewabilityConfigCallbackPair Methods​ flashScrollIndicators()​ React TSXflashScrollIndicators();
短暂显示滚动指示器。 getNativeScrollRef()​ React TSXgetNativeScrollRef(): React.ElementRef;
提供对底层滚动组件的引用。 getScrollResponder()​ React TSXgetScrollResponder(): ScrollResponderMixin;
提供对底层滚动响应器的句柄。 getScrollableNode()​ React TSXgetScrollableNode(): any;
提供对底层滚动节点的句柄。 scrollToEnd()​ React TSXscrollToEnd(params?: {animated?: boolean});
滚动到内容末尾。若未提供 getItemLayout 属性,可能会出现卡顿。 Parameters: NameTypeparamsobject 有效的 params 键包括: 'animated' (boolean) - 列表在滚动时是否执行动画。默认为 true。 scrollToIndex()​ React TSXscrollToIndex: (params: {
index: number;
animated?: boolean;
viewOffset?: number;
viewPosition?: number;
});
滚动到指定索引处的元素,使其位于可视区域内:viewPosition 为 0 表示置于顶部,1 表示置于底部,0.5 表示居中显示。 注意:如未指定 getItemLayout 属性,则无法滚动到渲染窗口以外的位置。 参数: 名称类型params 必填object 有效的 params 键包括: 'animated'(boolean)- 滚动时是否带动画效果。默认为 true。 'index'(number)- 要滚动到的索引。必填。 'viewOffset'(number)- 一个固定的像素值,用于偏移最终的目标位置。 'viewPosition'(number)- 值为 0 时将 index 指定的元素置于顶部,1 置于底部,0.5 居中显示。 scrollToItem()​ React TSXscrollToItem(params: {
animated?: ?boolean,
item: Item,
viewPosition?: number,
});
需要线性扫描数据才能定位,如有可能请改用 scrollToIndex。 注意:如未指定 getItemLayout 属性,则无法滚动到渲染窗口以外的位置。 参数: 名称类型params 必填object 有效的 params 键包括: 'animated'(boolean)- 滚动时是否带动画效果。默认为 true。 'item'(object)- 要滚动到的元素。必填。 'viewPosition'(number) scrollToOffset()​ React TSXscrollToOffset(params: {
offset: number;
animated?: boolean;
});
滚动到列表中指定的像素偏移位置。 参数: 名称类型params 必填object 有效的 params 键包括: 'offset'(number)- 要滚动到的偏移量。当 horizontal 为 true 时,该偏移量为 x 值,其他情况下为 y 值。必填。 'animated'(boolean)- 滚动时是否带动画效果。默认为 true。

评论 (0)