从入门小白到精通,玩转React Native鸿蒙跨平台开发:订单搜索长列表场景演示
React Native高性能列表实现摘要:该代码基于VirtualizedList构建了一个优化列表应用,包含数据管理、搜索过滤和收藏功能。核心特性包括:1) 使用useState管理50项初始数据及状态;2) 通过filteredData实现实时搜索过滤;3) 采用VirtualizedList的惰性渲染机制(initialNumToRender=4)提升性能;4) 实现收藏功能的状态更新和列
这段React Native代码实现了一个高性能的虚拟化列表应用,其核心原理基于React Native的VirtualizedList组件和React的状态管理机制。
在数据层面,应用通过useState钩子管理多个状态:原始数据、加载状态、搜索查询和选中项。初始数据通过Array.from生成50个具有唯一ID、标题、描述和收藏状态的对象。搜索功能通过filteredData实现,它根据searchQuery对数据进行实时过滤,只显示标题匹配搜索关键词的项。收藏功能通过handleFavoritePress方法实现,它遍历数据数组并切换指定ID项目的isFavorite状态。
列表渲染优化的关键在于VirtualizedList组件的工作机制。与普通列表不同,VirtualizedList通过getItemCount和getItem这两个关键函数来动态计算和获取列表项,而不是一次性渲染所有数据。initialNumToRender={4}意味着初始只渲染4个可见项,当用户滚动时再按需渲染后续项。这种惰性渲染机制极大地提升了长列表的性能,特别是在移动设备上。keyExtractor确保每个列表项都有稳定的唯一标识,这对于高效的列表更新至关重要。
实际项目演示:
这段React Native代码实现了一个基于VirtualizedList的高性能列表应用,主要原理可以分为数据管理、列表渲染优化和用户交互三个核心层面。
在数据层面,代码使用React的useState钩子来管理应用状态。初始数据通过Array.from方法生成50个具有唯一ID、标题、描述和收藏状态的对象。搜索功能通过filteredData实现,它根据searchQuery状态对数据进行实时过滤,只显示标题匹配搜索关键词的项。收藏功能通过handleFavoritePress方法实现,它遍历数据数组并切换指定ID项目的isFavorite状态。这种不可变数据更新模式确保了状态变化的可追踪性。
import React, { useState } from 'react';
import { SafeAreaView, View, VirtualizedList, StyleSheet, Text, TouchableOpacity, TextInput, ActivityIndicator } from 'react-native';
import Constants from 'expo-constants';
const DATA = Array.from({ length: 50 }, (_, index) => ({
id: Math.random().toString(12).substring(0),
title: `Item ${index + 1}`,
description: `This is the description for item ${index + 1}`,
isFavorite: false,
}));
const getItem = (data, index) => data[index];
const getItemCount = (data) => data.length;
const Item = ({ title, description, isFavorite, onPress, onFavoritePress }) => {
return (
<TouchableOpacity onPress={onPress} style={styles.item}>
<View style={styles.itemContent}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.description}>{description}</Text>
</View>
<TouchableOpacity onPress={onFavoritePress} style={styles.favoriteButton}>
<Text style={styles.favoriteText}>{isFavorite ? '❤️' : '🤍'}</Text>
</TouchableOpacity>
</TouchableOpacity>
);
};
const VirtualizedListExample = () => {
const [data, setData] = useState(DATA);
const [loading, setLoading] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
const [selectedItem, setSelectedItem] = useState(null);
const handleRefresh = () => {
setLoading(true);
setTimeout(() => {
setData(DATA);
setLoading(false);
}, 1000);
};
const handleLoadMore = () => {
setLoading(true);
setTimeout(() => {
const newData = Array.from({ length: 10 }, (_, index) => ({
id: Math.random().toString(12).substring(0),
title: `Item ${data.length + index + 1}`,
description: `This is the description for item ${data.length + index + 1}`,
isFavorite: false,
}));
setData([...data, ...newData]);
setLoading(false);
}, 1000);
};
const handleItemPress = (item) => {
setSelectedItem(item);
};
const handleFavoritePress = (itemId) => {
setData(
data.map((item) =>
item.id === itemId ? { ...item, isFavorite: !item.isFavorite } : item
)
);
};
const filteredData = data.filter((item) =>
item.title.toLowerCase().includes(searchQuery.toLowerCase())
);
return (
<SafeAreaView style={styles.container}>
<TextInput
style={styles.searchInput}
placeholder="Search items..."
value={searchQuery}
onChangeText={setSearchQuery}
/>
{selectedItem && (
<View style={styles.selectedItemContainer}>
<Text style={styles.selectedItemTitle}>{selectedItem.title}</Text>
<Text style={styles.selectedItemDescription}>
{selectedItem.description}
</Text>
</View>
)}
<VirtualizedList
data={filteredData}
initialNumToRender={4}
renderItem={({ item }) => (
<Item
title={item.title}
description={item.description}
isFavorite={item.isFavorite}
onPress={() => handleItemPress(item)}
onFavoritePress={() => handleFavoritePress(item.id)}
/>
)}
keyExtractor={(item) => item.id}
getItemCount={getItemCount}
getItem={getItem}
onRefresh={handleRefresh}
refreshing={loading}
/>
<TouchableOpacity onPress={handleLoadMore} style={styles.loadMoreButton}>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.loadMoreText}>Load More</Text>
)}
</TouchableOpacity>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
},
searchInput: {
padding: 10,
margin: 16,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
},
item: {
backgroundColor: '#f9c2ff',
height: 100,
justifyContent: 'space-between',
marginVertical: 8,
marginHorizontal: 16,
padding: 20,
borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
},
itemContent: {
flex: 1,
},
title: {
fontSize: 18,
fontWeight: 'bold',
},
description: {
fontSize: 14,
color: '#666',
},
favoriteButton: {
padding: 10,
},
favoriteText: {
fontSize: 20,
},
selectedItemContainer: {
padding: 16,
backgroundColor: '#e6e6e6',
marginHorizontal: 16,
borderRadius: 8,
marginBottom: 8,
},
selectedItemTitle: {
fontSize: 16,
fontWeight: 'bold',
},
selectedItemDescription: {
fontSize: 14,
color: '#666',
},
loadMoreButton: {
backgroundColor: '#6200ee',
padding: 16,
margin: 16,
borderRadius: 8,
alignItems: 'center',
},
loadMoreText: {
color: '#fff',
fontWeight: 'bold',
},
});
export default VirtualizedListExample;
列表渲染优化的核心在于VirtualizedList组件。与普通FlatList不同,VirtualizedList通过getItemCount和getItem这两个关键函数来动态计算和获取列表项,而不是一次性渲染所有数据。initialNumToRender={4}意味着初始只渲染4个可见项,当用户滚动时再按需渲染后续项。这种惰性渲染机制极大地提升了长列表的性能,特别是在移动设备上。keyExtractor确保每个列表项都有稳定的唯一标识,这对于高效的列表更新至关重要。
用户交互层面实现了完整的操作闭环。搜索输入框通过TextInput组件提供实时搜索功能,onChangeText直接更新searchQuery状态。下拉刷新功能通过onRefresh和refreshing属性实现,handleRefresh方法在触发后模拟1秒的网络延迟,然后重置数据到初始状态。"加载更多"功能通过handleLoadMore实现,它在现有数据末尾添加10个新项目,模拟分页加载场景。项目选择功能通过handleItemPress记录当前选中的项目,并在列表上方显示选中项的详细信息。

整个应用的UI布局采用SafeAreaView确保内容不会与设备刘海或状态栏重叠。样式系统通过StyleSheet.create创建,提供一致的视觉设计,包括圆角边框、阴影效果和合理的间距。加载状态通过ActivityIndicator组件可视化显示,在异步操作期间提供用户反馈。这种架构既保证了大数据量下的流畅体验,又提供了丰富的交互功能,展示了React Native在构建复杂列表界面时的最佳实践。
打包
接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

最后运行效果图如下显示:

用户交互层面实现了完整的操作闭环。搜索输入框通过TextInput组件提供实时搜索功能,onChangeText直接更新searchQuery状态。下拉刷新功能通过onRefresh和refreshing属性实现,handleRefresh方法在触发后模拟1秒的网络延迟,然后重置数据到初始状态。"加载更多"功能通过handleLoadMore实现,它在现有数据末尾添加10个新项目,模拟分页加载场景。项目选择功能通过handleItemPress记录当前选中的项目,并在列表上方显示选中项的详细信息。
整个应用的UI布局采用SafeAreaView确保内容不会与设备刘海或状态栏重叠。样式系统通过StyleSheet.create创建,提供一致的视觉设计,包括圆角边框、阴影效果和合理的间距。加载状态通过ActivityIndicator组件可视化显示,在异步操作期间提供用户反馈。这种架构既保证了大数据量下的流畅体验,又提供了丰富的交互功能,展示了React Native在构建复杂列表界面时的最佳实践。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
更多推荐



所有评论(0)