Skip to content

React Native - ListView

React Native - 使用 FlatList 显示列表

Section titled “React Native - 使用 FlatList 显示列表”

本章讲解如何在 React Native 中高效地显示可滚动的数据列表。虽然对于短列表可以使用 ScrollView 和 map(),但对于长列表或动态列表,推荐使用 FlatList 组件,因为它具有性能优化(例如,项虚拟化/item virtualization)。

旧教程中提到的 ListView 组件现已弃用。FlatList 是其现代替代品。

FlatList 需要两个主要的 props:data(数据项数组)和 renderItem(一个为每个数据项返回 React 元素的函数)。

MyListComponent.js

import React, { useState } from 'react';
import { FlatList, Text, View, TouchableOpacity, StyleSheet, Alert } from 'react-native';
const MyListComponent = () => {
const [people, setPeople] = useState([
{ id: '1', name: 'Alice', age: 30 },
{ id: '2', name: 'Bob', age: 24 },
{ id: '3', name: 'Charlie', age: 35 },
{ id: '4', name: 'Diana', age: 28 },
{ id: '5', name: 'Edward', age: 40 },
// 添加更多项以查看滚动行为
{ id: '6', name: 'Fiona', age: 22 },
{ id: '7', name: 'George', age: 31 },
{ id: '8', name: 'Hannah', age: 29 },
{ id: '9', name: 'Ian', age: 26 },
{ id: '10', name: 'Julia', age: 33 },
]);
const handleItemPress = (item) => {
Alert.alert('Item Pressed', `You selected ${item.name}, aged ${item.age}.`);
};
// renderItem 函数接收一个包含 'item' 属性的对象
const renderListItem = ({ item }) => (
<TouchableOpacity onPress={() => handleItemPress(item)} style={styles.itemContainer}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemAge}>Age: {item.age}</Text>
</TouchableOpacity>
);
return (
<View style={styles.container}>
<Text style={styles.title}>User List</Text>
<FlatList
data={people}
renderItem={renderListItem}
keyExtractor={(item) => item.id} // 对于性能和项目稳定性很重要
// 可选的 props:
// ItemSeparatorComponent={() => <View style={styles.separator} />} // 项目之间的分隔线组件
// ListHeaderComponent={<Text style={styles.listHeader}>Header</Text>} // 列表头部组件
// ListFooterComponent={<Text style={styles.listFooter}>Footer</Text>} // 列表尾部组件
// ListEmptyComponent={<Text style={styles.emptyList}>No users found.</Text>} // 列表为空时显示的组件
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20,
backgroundColor: '#f0f0f0',
},
title: {
fontSize: 22,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 15,
color: '#333',
}, itemContainer: {
backgroundColor: '#ffffff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3,
},
itemName: {
fontSize: 18,
color: '#333333',
fontWeight: '500',
},
itemAge: {
fontSize: 14,
color: '#666666',
marginTop: 4,
}, separator: {
height: 1,
backgroundColor: '#e0e0e0',
marginHorizontal: 16,
},
listHeader: {
fontSize: 18, padding: 10, textAlign: 'center', backgroundColor: '#ddd'
},
listFooter: {
fontSize: 18, padding: 10, textAlign: 'center', backgroundColor: '#ddd'
},
emptyList: {
textAlign: 'center', marginTop: 50, fontSize: 16, color: 'gray'
}
});
export default MyListComponent;
  • data:一个对象数组。每个对象代表列表中的一个数据项。
  • renderItem:一个函数,它接收一个对象 { item, index, separators },并返回要为该数据项渲染的 React 组件。我们通常会解构出 item。
  • keyExtractor:一个函数,接收数据项及其索引,并返回该数据项的唯一字符串 key。这对于 React 在更新、添加或删除列表项时高效管理列表项至关重要。如果数据具有唯一的 ID,通常使用 item.id。
  • TouchableOpacity:用于使每个列表项可点击,触发一个带有所选数据项详细信息的 alert。

运行此组件时,您将看到一个可滚动的姓名和年龄列表。点击列表项会显示一个包含该人员姓名和年龄的 alert。

为什么选择 FlatList 而不是 ScrollView + map()?

Section titled “为什么选择 FlatList 而不是 ScrollView + map()?”
  • 性能:FlatList 实现了数据项虚拟化(item virtualization)。它仅渲染当前屏幕上可见的数据项(以及少量屏幕外的项以实现平滑滚动)。这显著提高了长列表的性能和内存使用率。
  • 内置功能:FlatList 开箱即用地提供了许多功能,如下拉刷新(pull-to-refresh)、无限滚动支持、头部/尾部组件、分隔符、多列布局等。
  • ItemSeparatorComponent:在每个数据项之间渲染一个组件(例如,一条分隔线)。
  • ListHeaderComponent:在列表顶部渲染一个组件。
  • ListFooterComponent:在列表底部渲染一个组件。
  • ListEmptyComponent:当 data 数组为空时渲染一个组件。
  • onEndReached:当用户滚动接近列表末尾时调用(用于无限滚动)。
  • onRefresh / refreshing:用于下拉刷新功能。

对于分区的列表,React Native 还提供了 SectionList。了解更多关于 FlatList 的信息,请查阅官方文档:https://reactnative.dev/docs/flatlist