import React, { useState, useEffect, useCallback } from 'react'; import { View, Text, StyleSheet, TextInput, TouchableOpacity, FlatList, Keyboard, Platform, SafeAreaView, StatusBar } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import Ionicons from '@expo/vector-icons/Ionicons'; import { useNavigation, useFocusEffect } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; // 图标组件 - 使用React.memo优化渲染 const IconComponent = React.memo(({ name, size, color }: { name: string; size: number; color: string }) => { const Icon = Ionicons as any; return ; }); // 搜索历史存储键 const SEARCH_HISTORY_KEY = 'search_history'; // 历史记录项组件 - 使用React.memo优化渲染 const HistoryItem = React.memo(({ item, onPress, onRemove }: { item: string; onPress: (item: string) => void; onRemove: (item: string) => void }) => ( onPress(item)} > {item} onRemove(item)}> )); // 热门标签组件 - 使用React.memo优化渲染 const HotTagItem = React.memo(({ tag, onPress }: { tag: string; onPress: (tag: string) => void }) => ( onPress(tag)} > {tag} )); export const SearchScreen = () => { const [searchText, setSearchText] = useState(''); const [searchHistory, setSearchHistory] = useState([]); const [isLoading, setIsLoading] = useState(true); const navigation = useNavigation>(); // 预设热门搜索标签 const hotSearchTags = ['手机', '耳机', '电脑', '平板', '手表', '相机', '家电', '食品']; // 只在页面聚焦时加载历史记录,而不是每次组件挂载 useFocusEffect( useCallback(() => { loadSearchHistory(); }, []) ); // 从AsyncStorage加载搜索历史 - 优化异步操作 const loadSearchHistory = async () => { try { setIsLoading(true); const historyJson = await AsyncStorage.getItem(SEARCH_HISTORY_KEY); if (historyJson) { const history = JSON.parse(historyJson); setSearchHistory(history); } } catch (error) { console.error('Failed to load search history:', error); } finally { setIsLoading(false); } }; // 保存搜索历史 - 使用useCallback优化函数引用 const saveSearchHistory = useCallback(async (searchTerm: string) => { try { // 如果搜索词为空,不保存 if (!searchTerm.trim()) return; // 创建新的历史记录,将新搜索词放在最前面 const newHistory = [searchTerm, ...searchHistory.filter(item => item !== searchTerm)]; // 只保留最近10条 const trimmedHistory = newHistory.length > 10 ? newHistory.slice(0, 10) : newHistory; // 先更新UI状态,再进行异步存储操作 setSearchHistory(trimmedHistory); // 异步存储操作不阻塞UI AsyncStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(trimmedHistory)) .catch(error => console.error('Failed to save search history:', error)); } catch (error) { console.error('Failed to process search history:', error); } }, [searchHistory]); // 清除指定的搜索历史 - 使用useCallback优化函数引用 const removeSearchHistoryItem = useCallback(async (searchTerm: string) => { try { const newHistory = searchHistory.filter(item => item !== searchTerm); // 先更新UI状态,再进行异步存储操作 setSearchHistory(newHistory); // 异步存储操作不阻塞UI AsyncStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(newHistory)) .catch(error => console.error('Failed to remove search history item:', error)); } catch (error) { console.error('Failed to remove search history item:', error); } }, [searchHistory]); // 清除所有搜索历史 - 使用useCallback优化函数引用 const clearAllSearchHistory = useCallback(async () => { try { // 先更新UI状态,再进行异步存储操作 setSearchHistory([]); // 异步存储操作不阻塞UI AsyncStorage.removeItem(SEARCH_HISTORY_KEY) .catch(error => console.error('Failed to clear search history:', error)); } catch (error) { console.error('Failed to clear search history:', error); } }, []); // 处理搜索提交 - 使用useCallback优化函数引用 const handleSearch = useCallback(() => { if (searchText.trim()) { saveSearchHistory(searchText.trim()); Keyboard.dismiss(); // 导航到搜索结果页面,并传递搜索关键词 navigation.navigate('SearchResult', { keyword: searchText.trim() }); } }, [searchText, saveSearchHistory, navigation]); // 点击历史记录项 - 使用useCallback优化函数引用 const handleHistoryItemPress = useCallback((item: string) => { setSearchText(item); saveSearchHistory(item); // 导航到搜索结果页面,并传递搜索关键词 navigation.navigate('SearchResult', { keyword: item }); }, [saveSearchHistory, navigation]); // 渲染历史记录项 - 使用useCallback优化函数引用 const renderHistoryItem = useCallback(({ item }: { item: string }) => ( ), [handleHistoryItemPress, removeSearchHistoryItem]); // 处理热门标签点击 - 使用useCallback优化函数引用 const handleHotTagPress = useCallback((tag: string) => { setSearchText(tag); saveSearchHistory(tag); // 导航到搜索结果页面,并传递搜索关键词 navigation.navigate('SearchResult', { keyword: tag }); }, [saveSearchHistory, navigation]); return ( {/* 搜索栏 */} {searchText.length > 0 && ( setSearchText('')}> )} navigation.goBack()}> 取消 {/* 历史搜索记录 */} {!isLoading && searchHistory.length > 0 && ( 历史搜索 `history-${index}`} renderItem={renderHistoryItem} style={styles.historyList} keyboardShouldPersistTaps="handled" initialNumToRender={5} maxToRenderPerBatch={10} removeClippedSubviews={true} windowSize={5} /> )} {/* 热门搜索 */} 热门搜索 {hotSearchTags.map((tag, index) => ( ))} ); }; const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: '#ffffff', }, container: { flex: 1, backgroundColor: '#ffffff', }, searchHeader: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 15, paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: '#f0f0f0', }, searchBar: { flex: 1, flexDirection: 'row', alignItems: 'center', backgroundColor: '#f5f5f5', borderRadius: 20, paddingHorizontal: 15, height: 40, }, searchInput: { flex: 1, marginLeft: 8, fontSize: 16, color: '#333', height: 40, }, cancelButton: { marginLeft: 10, padding: 5, }, cancelButtonText: { fontSize: 16, color: '#333', }, historyContainer: { padding: 15, }, historyHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10, }, historyTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', }, historyList: { marginTop: 5, }, historyItemContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: '#f0f0f0', }, historyItem: { flex: 1, flexDirection: 'row', alignItems: 'center', }, historyItemText: { fontSize: 14, color: '#333', marginLeft: 10, }, hotSearchContainer: { padding: 15, }, hotSearchTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', marginBottom: 10, }, hotSearchTags: { flexDirection: 'row', flexWrap: 'wrap', }, hotSearchTag: { backgroundColor: '#f5f5f5', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 15, marginRight: 10, marginBottom: 10, }, hotSearchTagText: { fontSize: 14, color: '#333', }, });