从入门小白到精通,玩转React Native鸿蒙跨平台开发:FlatList高性能列表组件
React Native的FlatList是一个高性能列表组件,支持跨平台、水平布局、下拉刷新、上拉加载等功能。它基于VirtualizedList实现,具有内存优化特性,但快速滚动时可能出现空白内容。使用时需注意:1) 为每项提供唯一key;2) 正确处理数据更新以避免渲染问题;3) 行组件滑出后状态不保留。示例代码展示了基本用法,包括数据定义、行组件渲染和FlatList配置。对于性能优化,建
FlatList
高性能的简单列表组件,支持下面这些常用的功能:
- 完全跨平台。
- 支持水平布局模式。
- 行组件显示或隐藏时可配置回调事件。
- 支持单独的头部组件。
- 支持单独的尾部组件。
- 支持自定义行间分隔线。
- 支持下拉刷新。
- 支持上拉加载。
- 支持跳转到指定行(ScrollToIndex)。
- 支持多列布局。
要呈现多列,请使用 numColumns 属性。使用这种方法而不是 flexWrap 布局可以防止与项目高度逻辑发生冲突。
下面是一个较复杂的例子,其中演示了如何利用PureComponent来进一步优化性能和减少 bug 产生的可能(以下这段文字需要你深刻理解 shouldComponentUpdate, memo 的机制,以及 Component 和 PureComponent 的不同,如果不了解就先跳过吧)。
-
对于MyListItem组件来说,其onPressItem属性使用箭头函数而非 bind 的方式进行绑定,使其不会在每次列表重新 render 时生成一个新的函数,从而保证了 props 的不变性(当然前提是 id、selected和title也没变),不会触发自身无谓的重新 render。换句话说,如果你是用 bind 来绑定onPressItem,每次都会生成一个新的函数,导致 props 在===比较时返回 false,从而触发自身的一次不必要的重新 render。
-
给FlatList指定extraData={this.state}属性,是为了保证state.selected变化时,能够正确触发FlatList的更新。如果不指定此属性,则FlatList不会触发更新,因为它是一个PureComponent,其 props 在===比较中没有变化则不会触发更新。
-
keyExtractor属性指定使用 id 作为列表每一项的 key。
本组件实质是基于组件的封装,继承了其所有 props(也包括所有)的 props),但在本文档中没有列出。此外还有下面这些需要注意的事项:
-
当某行滑出渲染区域之外后,其内部状态将不会保留。请确保你在行组件以外的地方保留了数据。
-
本组件继承自PureComponent而非通常的Component,这意味着如果其props在浅比较中是相等的,则不会重新渲染。所以请先检查你的renderItem函数所依赖的props数据(包括data属性以及可能用到的父组件的 state),如果是一个引用类型(Object 或者数组都是引用类型),则需要先修改其引用地址(比如先复制到一个新的 Object 或者数组中),然后再修改其值,否则界面很可能不会刷新。(译注:这一段不了解的朋友建议先学习下js 中的基本类型和引用类型。)
-
为了优化内存占用同时保持滑动的流畅,列表内容会在屏幕外异步绘制。这意味着如果用户滑动的速度超过渲染的速度,则会先看到空白的内容。这是为了优化不得不作出的妥协,你可以根据自己的需求调整相应的参数,而我们也在设法持续改进。
默认情况下每行都需要提供一个不重复的 key 属性。你也可以提供一个keyExtractor函数来生成 key。
ScrollView Props
继承所有ScrollView 的 Props。但如果嵌套在其他同滚动方向的 FlatList 中则无效。
renderItem({
item: ItemT,
index: number,
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
}
}): JSX.Element;
从data中获取一个项目并将其渲染到列表中。
如果需要,提供附加的元数据,如index,以及一个更通用的separators.updateProps函数,该函数允许您设置要更改前导分隔符或尾随分隔符的渲染的任何属性,以防常见的highlight和unhighlight(设置highlighted: boolean属性)对您的用例不足够。
类型
函数
- item(对象):要渲染的来自data的项目。
- index(数字):在data数组中对应于此项目的索引。
- separators(对象)
- highlight(函数)
- unhighlight(函数)
- updateProps(函数)
- select(枚举(‘leading’, ‘trailing’))
- newProps(对象)
实际案例:
import React from 'react';
import {
SafeAreaView,
View,
FlatList,
StyleSheet,
Text,
StatusBar,
} from 'react-native';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
type ItemProps = {title: string};
const Item = ({title}: ItemProps) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={({item}) => <Item title={item.title} />}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
backgroundColor: '#f5f5f5',
},
item: {
backgroundColor: '#ffffff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
},
});
export default App;
这段React Native代码主要展示了列表渲染的核心实现方式。代码通过FlatList组件构建了一个可滚动的数据列表界面,其中包含多个重复的测试数据项用于展示滚动效果。每个列表项都采用了卡片式设计,具有圆角边框和阴影效果来增强视觉层次。
在数据结构方面,代码定义了包含id和title属性的对象数组,使用UUID格式的字符串作为唯一标识符。Item组件作为列表项的渲染单元,接收title属性并展示在精心设计的容器中。样式系统通过StyleSheet.create方法集中管理,确保了界面元素的一致性。
代码还体现了React Native的跨平台特性,通过StatusBar.currentHeight自动适配不同设备的顶部状态栏高度。整体实现采用了函数式组件的开发模式,展示了现代React开发中类型定义、组件封装和样式组织的最佳实践。

打包
接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

最后运行效果图如下显示:
更多推荐



所有评论(0)