跳到主要内容

使用方法

如果您熟悉 FlatList,那么您已经知道如何使用 FlashList 了。 您可以通过更改组件名称并添加 estimatedItemSize 属性来尝试 FlashList,或者参考下面的示例

import React from "react";
import { View, Text, StatusBar } from "react-native";
import { FlashList } from "@shopify/flash-list";

const DATA = [
{
title: "First Item",
},
{
title: "Second Item",
},
];

const MyList = () => {
return (
<FlashList
data={DATA}
renderItem={({ item }) => <Text>{item.title}</Text>}
estimatedItemSize={200}
/>
);
};

为了避免常见的陷阱,您还可以根据我们自己的经验,按照以下步骤从 FlatList 迁移

  1. FlatList 切换到 FlashList 并渲染列表一次。您应该会看到一个关于缺少 estimatedItemSize 的警告和一个建议。直接将此值设置为属性。
  2. 重要提示:扫描您的 renderItem 层级结构,查找显式的 key 属性定义并删除它们。如果您正在使用 .map(),请使用索引作为键。
  3. 检查您的 renderItem 层级结构,查找使用 useState 的组件,并验证如果将不同的项目传递给该组件,是否需要重置该状态(请参阅 回收
  4. 如果您的列表具有异构视图,请使用 getItemType 属性将它们的类型传递给 FlashList 以提高性能。
  5. 请勿在启用 JS 开发模式的情况下测试性能。请确保您处于发布模式。由于渲染缓冲区较小,FlashList 在开发模式下可能会显得较慢。
estimatedItemSize

estimatedItemSize 对于实现最佳性能是必要的。

FlatList 的大多数属性在 FlashList 中也可用。 本文档包含 FlatList 和额外的 FlashList 属性,应作为主要参考。 但是您也可以在此处阅读有关 FlatListFlashList 中可用的属性的更多信息。

属性

FlashList 也有一些独特的属性。您已经了解了 estimatedItemSize,但还有更多属性可用于进行微调。

renderItem

注意

必需

renderItem: ({ item, index, target, extraData }) => void;

data 中获取一个项目并将其渲染到列表中。典型用法

renderItem = ({item}) => (
<Text>{item.title}</Text>
);
...
<FlashList data={[{title: 'Title Text', key: 'item1'}]} renderItem={renderItem} />

提供其他元数据,如 index

  • item (Object):正在渲染的来自 data 的项目。
  • index (number):此项目在 data 数组中对应的索引。
  • target (string) FlashList 可能会出于多种原因渲染您的项目。
    • Cell - 这是您的列表项。
    • Measurement - 可能被调用以进行大小测量,并且不可见。您可以在分析中忽略此项。
    • StickyHeader - 这是您的粘性标题。当您的项目用作粘性标题时,请使用此项来更改其外观。
  • extraData (Object) - 这与传递给 FlashListextraData 属性相同。

data

注意

必需

为简单起见,数据是给定类型的项目的简单数组。

data: ItemT[];

estimatedItemSize

estimatedItemSize?: number;

estimatedItemSize 是一个数字值,它向 FlashList 提示项目在渲染前的近似大小。然后,FlashList 可以使用此信息来决定在初始加载和滚动时需要在屏幕上绘制多少个项目。如果大多数项目都是不同大小,您可以考虑平均值或中值,如果大多数项目都是相同大小,则只需使用该数字。快速查看 Element Inspector 可以帮助您确定这一点。如果您在两个值之间感到困惑,则较小的值是更好的选择。如果您没有指定此属性,您将收到一个警告,其中包含您可以使用的值。我们建议不要忽略该警告并在列表到达您的用户之前定义 estimatedItemSize


CellRendererComponent

每个单元格都使用此元素渲染。可以是 React 组件类,也可以是渲染函数。根组件应始终是 CellContainer,这也是使用的默认组件。确保将原始 props 传递给返回的 CellContainerprops 包含以下属性

  • onLayout:用于更新有关真实 CellContainer 布局的数据的方法
  • index:列表中单元格的索引,如果需要,您可以使用此索引查询数据
  • styleCellContainer 的样式,包括
    • flexDirection:取决于您的列表是水平还是垂直
    • position:此值将为 absolute,因为这就是 FlashList 定位元素的方式
    • left:确定元素在 x 轴上的位置
    • top:确定元素在 y 轴上的位置
    • width:确定元素的宽度(当列表垂直时存在)
    • height:确定元素的高度(当列表水平时存在)

react-native-reanimated 一起使用时,您可以将 CellContainer 包装在 Animated.createAnimatedComponent 中(这类似于使用 Animated.View

注意

更改单元格的布局可能会与本机布局操作冲突。您可能需要将 disableAutoLayout 设置为 true 以防止这种情况。

const AnimatedCellContainer = Animated.createAnimatedComponent(CellContainer);
return (
<FlashList
CellRendererComponent={(props) => {
return (
<AnimatedCellContainer {...props} style={...}>
);
}}
/>
);
CellRendererComponent?: React.ComponentType<any> | undefined;

ItemSeparatorComponent

在每个项目之间渲染,但不在顶部或底部渲染。默认情况下,会提供 leadingItemtrailingItem(如果可用)属性。

ItemSeparatorComponent?: React.ComponentType<any>;

ListEmptyComponent

当列表为空时渲染。可以是 React 组件(例如 SomeComponent),也可以是 React 元素(例如 <SomeComponent />)。

ListEmptyComponent?: React.ComponentType<any> | React.ReactElement<any, string | React.JSXElementConstructor<any>>;

ListFooterComponent

在所有项目的底部渲染。可以是 React 组件(例如 SomeComponent),也可以是 React 元素(例如 <SomeComponent />)。

ListFooterComponent?: React.ComponentType<any> | React.ReactElement<any, string | React.JSXElementConstructor<any>>;

ListFooterComponentStyle

用于 ListFooterComponent 的内部视图的样式。

ListFooterComponentStyle?: StyleProp<ViewStyle>;

ListHeaderComponent

在所有项目的顶部渲染。可以是 React 组件(例如 SomeComponent),也可以是 React 元素(例如 <SomeComponent />)。

ListHeaderComponent?: React.ComponentType<any> | React.ReactElement<any, string | React.JSXElementConstructor<any>>;

ListHeaderComponentStyle

用于 ListHeaderComponent 的内部视图的样式。

ListHeaderComponentStyle?: StyleProp<ViewStyle>;

contentContainerStyle

contentContainerStyle?: ContentStyle;

export type ContentStyle = Pick<
ViewStyle,
| "backgroundColor"
| "paddingTop"
| "paddingLeft"
| "paddingRight"
| "paddingBottom"
| "padding"
| "paddingVertical"
| "paddingHorizontal"
>;

您可以使用 contentContainerStyle 来应用将应用于整个内容的内边距。例如,您可以应用此内边距,以便您的所有项目都具有前导和尾随空间。

disableAutoLayout

disableAutoLayout?: boolean;

FlashList 对其子项的布局应用了一些修复,这可能会与自定义 CellRendererComponent 实现冲突。您可以通过将其设置为 true 来禁用此行为。

注意

建议:当您对 CellRendererComponent 应用特殊行为时,请将其设置为 true。完成后,再次将其设置为 false

disableHorizontalListHeightMeasurement

disableHorizontalListHeightMeasurement?: boolean;

FlashList 尝试通过预先绘制额外的列表项来测量水平列表的大小。当在内容很少的列表中与 initialScrollIndex 一起使用时,这有时会导致问题。您可能会看到一些过度滚动。当设置为 true 时,列表的渲染大小需要是确定的(即,高度和宽度大于 0),因为 FlashList 将跳过渲染额外的项目以进行测量。默认值为 false

drawDistance

drawDistance?: number;

高级渲染的绘制距离(以 dp/px 为单位)。

estimatedFirstItemOffset

estimatedFirstItemOffset?: number;

estimatedFirstItemOffset 指定第一个项目从列表窗口的开头绘制的距离,或者列表的第一个项目(不是标题)的偏移量。如果您正在使用 initialScrollIndex 属性,则此属性是必需的。在初始绘制之前,列表不知道标题的大小或可能使用标题样式等应用的任何特殊边距/内边距。如果未提供此项,则 initialScrollIndex 可能不会滚动到提供的索引。

estimatedListSize

estimatedListSize?: { height: number; width: number }

列表的估计可见高度和宽度。它不是滚动内容大小。定义此属性将使列表能够立即渲染。如果没有它,列表首先需要测量其大小,这会导致第一次渲染时出现小延迟。

extraData

用于告诉列表重新渲染的标记属性(因为它实现了 PureComponent)。如果您的任何 renderItem、页眉、页脚等函数依赖于 data 属性之外的任何内容,请将其粘贴在此处并将其视为不可变的。

extraData?: any;

horizontal

如果为 true,则水平并排渲染项目,而不是垂直堆叠。默认为 false

horizontal?: boolean;

initialScrollIndex

不从第一个项目开始,而是从 initialScrollIndex 开始。

initialScrollIndex?: number;

inverted

反转滚动方向。使用 -1 的缩放变换。

inverted?: boolean;

keyExtractor

keyExtractor?: (item: object, index: number) => string;

用于提取指定索引处给定项目的唯一键。键用于优化性能。在进行布局动画以唯一标识动画组件时,也必须定义 keyExtractor

numColumns

多列只能使用 horizontal={false} 渲染,并且会像 flexWrap 布局一样呈 Z 字形。项目的高度应相同 - 不支持砌体布局。

numColumns?: number;

onBlankArea

onBlankArea?: (blankAreaEvent: {
offsetStart: number;
offsetEnd: number;
blankArea: number;
}) => void;

FlashList 会计算滚动期间或列表初始加载期间用户可见的空白区域。

报告的值

  • offsetStart:屏幕顶部可见的空白区域(向上滚动时)。如果值大于 0,则用户可见。
  • offsetEnd:屏幕末尾可见的空白区域(向下滚动时)。如果值大于 0,则用户可见。
  • blankAreaoffsetStartoffsetEnd 的最大值。您可能会看到负值,表示项目渲染在列表可见区域之外。
警告

即使空白是预期的(例如,当列表没有足够的项目来填充屏幕时),也会触发此回调。

注意

此事件与 JS 层的 onScroll 事件不同步,而是与原生方法 onDraw (Android) 和 layoutSubviews (iOS) 一起工作。

onEndReached

onEndReached?: () => void;

当滚动位置到达渲染内容的 onEndReachedThreshold 内时,调用一次。

onEndReachedThreshold

onEndReachedThreshold?: number;

列表底部边缘必须距离内容末尾多远(以列表的可见长度为单位)才能触发 onEndReached 回调。因此,值 0.5 将在内容末尾在列表可见长度的一半以内时触发 onEndReached

onLoad

onLoad: (info: { elapsedTimeInMs: number }) => void;

此事件会在列表在屏幕上绘制项目后触发一次。它还会报告 elapsedTimeInMs,即绘制项目所花费的时间。这是必需的,因为 FlashList 不会在第一个周期中渲染项目。项目会在第一次渲染结束时测量自身后绘制。如果您正在使用 ListEmptyComponent,则此事件会在 ListEmptyComponent 渲染后立即触发。

onViewableItemsChanged

interface ViewToken {
index: number;
isViewable: boolean;
item: string;
key: string;
timestamp: number;
}

onViewableItemsChanged?: ((info: {
viewableItems: ViewToken[];
changed: ViewToken[];
}) => void) | null | undefined

当行的可见性发生更改时(由 viewabilityConfig 属性定义)调用。changed 的数组包括可见和不可见项目的 ViewToken。您可以使用 isViewable 标志来筛选项目。

注意

如果您正在跟踪视图变为(不)可见的时间,请使用 timestamp 属性。我们不保证在未来可见性回调会立即发生 - 例如,它们可能会延迟到 JS 线程不那么繁忙时。

onRefresh

onRefresh?: () => void;

如果提供,将添加一个标准的 RefreshControl 以实现“下拉刷新”功能。请确保也正确设置 refreshing 属性。

getItemType

getItemType?: (
item: T,
index: number,
extraData?: any
) => string | number | undefined;

允许开发人员指定项目类型。如果列表中有不同类型的项目,这将改进回收。正确的类型将用于正确的项目。默认类型为 0。如果您不想更改索引,只需返回 undefined。您可以在此处看到如何使用此属性的示例。

性能

此方法调用非常频繁。请保持快速。

overrideItemLayout

overrideItemLayout?: (
layout: { span?: number; size?: number },
item: T,
index: number,
maxColumns: number,
extraData?: any
) => void;

此方法可用于提供显式的大小估计或更改项目的列跨度。

当您可以可靠地计算大小时,提供特定估计值是一个好主意。对于特定项目,FlashList 将优先使用此值而不是 estimatedItemSize。精确的估计值还将提高 scrollToIndex 方法和 initialScrollIndex 属性的精度。如果您的项目下方有 separator,则可以在估计值中包含其大小。

当您有网格布局(numColumns > 1)并且希望少数项目比其余项目大时,更改项目跨度很有用。

修改给定的布局。不要从该方法返回任何值。如果忽略此方法,FlashList 将回退到默认值。

性能

此方法调用非常频繁。请保持快速。

overrideProps

overrideProps?: object;

除了调试之外,我们不建议将此属性用于其他用途。列表的内部属性将被提供的覆盖。

progressViewOffset

progressViewOffset?: number;

当需要偏移量才能正确显示加载指示器时,请设置此值。

refreshControl

refreshControl?: React.ReactElement<any, string | React.JSXElementConstructor<any>>;

自定义刷新控件元素。设置后,它会覆盖内部构建的默认 <RefreshControl> 组件。onRefreshrefreshing 属性也会被忽略。仅适用于垂直 VirtualizedList。

refreshing

refreshing?: boolean;

在等待刷新中的新数据时,将其设置为 true。

renderScrollComponent

import type { ScrollViewProps } from "react-native";

renderScrollComponent?:
| React.ComponentType<ScrollViewProps>
| React.FC<ScrollViewProps>;

渲染为主滚动视图。

viewabilityConfig

interface ViewabilityConfig: {
minimumViewTime: number;
viewAreaCoveragePercentThreshold: number;
itemVisiblePercentThreshold: number;
waitForInteraction: boolean;
}

viewabilityConfig?: ViewabilityConfig;

viewabilityConfig 是用于确定项目是否可见的默认配置。

警告

不支持动态更改 viewabilityConfig

示例

<FlashList
viewabilityConfig={{
waitForInteraction: true,
itemVisiblePercentThreshold: 50,
minimumViewTime: 1000,
}}
...

minimumViewTime

项目在可见性回调触发之前必须实际可见的最短时间(以毫秒为单位)。较高的数字意味着在不停止的情况下滚动浏览内容不会将内容标记为可见。默认值为 250。我们不建议设置过低的值,以便在快速滚动时保持性能。

viewAreaCoveragePercentThreshold

部分遮挡的项目要算作“可见”必须覆盖的视口百分比,0-100。完全可见的项目始终被视为可见。值为 0 表示视口中的一个像素使该项目可见,而值为 100 表示项目必须完全可见或覆盖整个视口才能算作可见。

itemVisiblePercentThreshold

类似于 viewAreaCoveragePercentThreshold,但考虑的是可见的项目百分比,而不是它覆盖的可见区域的比例。

waitForInteraction

在用户滚动或在渲染后调用 recordInteraction 之前,任何内容都不会被视为可见。

viewabilityConfigCallbackPairs

type ViewabilityConfigCallbackPairs = ViewabilityConfigCallbackPair[];

interface ViewabilityConfigCallbackPair {
viewabilityConfig: ViewabilityConfig;
onViewableItemsChanged:
| ((info: { viewableItems: ViewToken[]; changed: ViewToken[] }) => void)
| null;
}

viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs | undefined;

ViewabilityConfig/onViewableItemsChanged 对的列表。当满足其相应的 ViewabilityConfig 的条件时,将调用特定的 onViewableItemsChanged

FlashList 方法

prepareForLayoutAnimationRender()

prepareForLayoutAnimationRender(): void;

在运行布局动画之前运行此方法,例如在删除元素时为其添加动画时。此方法会禁用下一帧的回收,以便布局动画运行良好。

警告

当对数据进行较大更改时,请避免使用此方法,因为该列表可能会绘制过多来运行动画,因为该方法会暂时禁用回收。单项插入或删除应平滑地添加动画。动画后的渲染将再次启用回收,您可以停止避免进行较大的数据更改。

recordInteraction()

recordInteraction();

告诉列表已发生交互,这应该触发可见性计算,例如,如果 waitForInteractions 为 true 且用户尚未滚动。例如,当用户点击项目或调用导航操作时,您通常应调用 recordInteraction()

recomputeViewableItems()

recomputeViewableItems();

重新触发可见性计算。对于命令式触发可见性计算很有用。

scrollToEnd()

scrollToEnd?: (params?: { animated?: boolean | null | undefined });

滚动到内容末尾。

scrollToIndex()

scrollToIndex(params: {
animated?: boolean | null | undefined;
index: number;
viewOffset?: number | undefined;
viewPosition?: number | undefined;
});

滚动到给定索引。

scrollToItem()

scrollToItem(params: {
animated?: boolean | null | undefined;
item: any;
viewPosition?: number | undefined;
});

滚动到给定项目。

scrollToOffset()

scrollToOffset(params: {
animated?: boolean | null | undefined;
offset: number;
});

滚动到列表中特定的内容像素偏移量。

参数 offset 需要滚动到的偏移量。如果 horizontal 为 true,则偏移量为 x 值,在任何其他情况下,偏移量为 y 值。

参数 animated(默认为 false)定义列表在滚动时是否应进行动画。

ScrollView 属性

FlashListFlatList 一样,在后台使用 ScrollView。您可以查看 React Native 文档中的 ScrollView,以查看详尽的属性列表。

不支持的 FlatList 属性

当前未实现 FlatList 中的以下属性

不支持的方法

由于底层实现的不同,如果将 FlatList 的某些属性移植到 FlashList,则不会带来任何价值

我们目前不打算实现这些属性。