如何在React中为DataTable添加搜索筛选功能?
给React Native DataTable添加搜索筛选功能的实现方案
实现步骤:
- 1. 新增搜索状态:用
useState创建状态存储用户输入的搜索关键词。 - 2. 编写筛选逻辑:根据关键词过滤原始
customers数据,保留匹配条目。 - 3. 绑定搜索输入框:给
TextInput添加onChangeText事件,实时更新搜索状态。 - 4. 适配分页逻辑:分页计算基于筛选后的数据,确保分页只针对搜索结果生效。
修改后的完整代码:
import { useState, useMemo } from 'react'; import { ScrollView, View, TouchableOpacity, Text, TextInput } from 'react-native'; import { DataTable } from 'react-native-paper'; export default function CustomerTable({ customers, handleBackButtonClick, handleRowClick }) { const [currentPage, setCurrentPage] = useState(0); const [selectedRow, setSelectedRow] = useState(null); const [searchQuery, setSearchQuery] = useState(''); // 新增搜索状态 const itemsPerPage = 10; // 可根据需求调整每页显示条数 // 缓存筛选结果,避免不必要重渲染 const filteredCustomers = useMemo(() => { if (!searchQuery.trim()) return customers; const lowerCaseQuery = searchQuery.toLowerCase(); return customers.filter(customer => customer.customer.toLowerCase().includes(lowerCaseQuery) || customer.address.toLowerCase().includes(lowerCaseQuery) || customer.mobileno.includes(lowerCaseQuery) || customer.plateno.toLowerCase().includes(lowerCaseQuery) ); }, [customers, searchQuery]); // 基于筛选后的数据处理分页 const handlePageChange = (page) => setCurrentPage(page); const displayedCustomers = useMemo(() => { const startIndex = currentPage * itemsPerPage; return filteredCustomers.slice(startIndex, startIndex + itemsPerPage); }, [filteredCustomers, currentPage, itemsPerPage]); return ( <> <ScrollView showsHorizontalScrollIndicator> <View style={styles.root}> <TouchableOpacity style={[styles.button, styles.buttonOutline]} onPress={handleBackButtonClick} > <Text style={styles.buttonOutlineText}>Back</Text> </TouchableOpacity> </View> <TextInput style={styles.searchInput} placeholder="Search by customer..." value={searchQuery} onChangeText={setSearchQuery} autoCapitalize="none" autoCorrect={false} /> <DataTable style={styles.container}> <DataTable.Header style={styles.tableHeader}> <DataTable.Title>Customer</DataTable.Title> <DataTable.Title>Address</DataTable.Title> <DataTable.Title>Mobile No.</DataTable.Title> <DataTable.Title>Plate No.</DataTable.Title> </DataTable.Header> {displayedCustomers.map((customer, index) => ( <TouchableOpacity key={customer.id || index} onPress={() => { handleRowClick(customer); setSelectedRow(customer); }} style={[ styles.row, selectedRow?.id === customer.id && styles.selectedRow ]} > <DataTable.Row> <DataTable.Cell>{customer.customer}</DataTable.Cell> <DataTable.Cell>{customer.address}</DataTable.Cell> <DataTable.Cell>{customer.mobileno}</DataTable.Cell> <DataTable.Cell>{customer.plateno}</DataTable.Cell> </DataTable.Row> </TouchableOpacity> ))} </DataTable> <DataTable.Pagination page={currentPage} numberOfPages={Math.ceil(filteredCustomers.length / itemsPerPage)} onPageChange={handlePageChange} /> </ScrollView> </> ); } // 原样式保留,此处省略具体样式代码 const styles = { root: {}, button: {}, buttonOutline: {}, buttonOutlineText: {}, searchInput: {}, container: {}, tableHeader: {}, row: {}, selectedRow: {} };
关键说明:
- 用
useMemo缓存筛选和分页结果,减少组件重渲染次数,提升性能。 - 搜索支持匹配表格内所有字段,手机号直接用字符串包含匹配,其他字段转小写后匹配,实现不区分大小写的搜索。
- 分页逻辑完全基于筛选后的数据,确保搜索后的分页仅展示匹配条目。
内容的提问来源于stack exchange,提问作者Les Jetskii
相关产品推荐
相关产品推荐

