React单表格多条件筛选实现咨询:勾选筛选项后表格数据联动更新问题
React 多条件联合筛选实现方案
核心逻辑是通过数组filter方法叠加多条件校验,未激活的筛选条件自动跳过,仅生效用户勾选/输入的限制规则,实现步骤如下:
1. 前置准备
首先导入React状态钩子,将原始数据源定义为不可变的常量,避免修改原始数据:
import { useState } from 'react'; // 原始数据源,固定不变 const mainArray = [ { id: 1, name: "foo", city: "dallas", category: "one", type: "A", active: "FALSE", }, { id: 2, name: "bar", city: "dallas", category: "one", type: "B", active: "FALSE", }, { id: 3, name: "jim", city: "san francisco", category: "one", type: "B", active: "TRUE", }, { id: 4, name: "jane", city: "denver", category: "two", type: "C", active: "FALSE", }, ]; // 提前对各筛选维度的值去重,避免渲染重复的筛选项 const filterOptions = { cities: [...new Set(mainArray.map(item => item.city))], categories: [...new Set(mainArray.map(item => item.category))], types: [...new Set(mainArray.map(item => item.type))], activeStatus: [...new Set(mainArray.map(item => item.active))] }
2. 定义筛选状态
在组件内定义所有筛选相关的状态,存储用户的选择:
function App() { // 存储各维度选中的筛选项,用Set结构方便判断存在性、增删元素 const [selectedCities, setSelectedCities] = useState(new Set()); const [selectedCategories, setSelectedCategories] = useState(new Set()); const [selectedTypes, setSelectedTypes] = useState(new Set()); const [selectedActive, setSelectedActive] = useState(new Set()); // 存储名称搜索关键词 const [nameKeyword, setNameKeyword] = useState('');
3. 核心筛选逻辑
计算筛选后的表格数据,多条件同时生效:
const filteredData = mainArray.filter(item => { // 城市筛选:如果有选中城市,则需要item的城市在选中集合内,否则不限制 const matchCity = selectedCities.size === 0 ? true : selectedCities.has(item.city); // 分类筛选 const matchCategory = selectedCategories.size === 0 ? true : selectedCategories.has(item.category); // 类型筛选 const matchType = selectedTypes.size === 0 ? true : selectedTypes.has(item.type); // 状态筛选 const matchActive = selectedActive.size === 0 ? true : selectedActive.has(item.active); // 名称筛选:关键词为空则不限制,否则做不区分大小写的模糊匹配 const matchName = nameKeyword.trim() === '' ? true : item.name.toLowerCase().includes(nameKeyword.toLowerCase()); // 所有条件同时满足才会被保留 return matchCity && matchCategory && matchType && matchActive && matchName; })
4. 封装筛选项更新方法
简化复选框选中状态切换的逻辑:
// 通用的Set状态更新方法 const toggleFilter = (setter, value) => { setter(prev => { const newSet = new Set(prev); if (newSet.has(value)) { newSet.delete(value); } else { newSet.add(value); } return newSet; }) }
5. 渲染部分修改
替换原来重复渲染的筛选项逻辑,表格使用筛选后的数据渲染:
return ( <div className="App"> {/* 城市筛选项 */} {filterOptions.cities.map(city => ( <div key={city}> <div> City : {city} <input type="checkbox" onChange={() => toggleFilter(setSelectedCities, city)} checked={selectedCities.has(city)} /> </div> <br /> </div> ))} {/* 分类筛选项 */} {filterOptions.categories.map(cate => ( <div key={cate}> <div> Category : {cate} <input type="checkbox" onChange={() => toggleFilter(setSelectedCategories, cate)} checked={selectedCategories.has(cate)} /> </div> <br /> </div> ))} {/* 类型筛选项 */} {filterOptions.types.map(type => ( <div key={type}> <div> Type : {type} <input type="checkbox" onChange={() => toggleFilter(setSelectedTypes, type)} checked={selectedTypes.has(type)} /> </div> <br /> </div> ))} {/* 状态筛选项 */} {filterOptions.activeStatus.map(status => ( <div key={status}> <div> Active : {status} <input type="checkbox" onChange={() => toggleFilter(setSelectedActive, status)} checked={selectedActive.has(status)} /> </div> <br /> </div> ))} {/* 名称搜索框 */} Name : <input type="text" value={nameKeyword} onChange={(e) => setNameKeyword(e.target.value)} /> <br /> {/* 表格部分,使用筛选后的filteredData渲染 */} <table border="5px" align="center"> <thead> <tr> <th>ID</th> <th>Name</th> <th>City</th> <th>Category</th> <th>Type</th> <th>Status</th> </tr> </thead> <tbody> {filteredData.map((item, i) => ( <tr key={i}> <td>{item.id}</td> <td>{item.name}</td> <td>{item.city}</td> <td>{item.category}</td> <td>{item.type}</td> <td>{item.active}</td> </tr> ))} </tbody> </table> </div> ); } export default App;
实现说明
- 所有筛选条件默认不激活,即展示全部数据
- 多个筛选条件同时勾选时,取交集结果,仅展示同时满足所有条件的数据
- 筛选项提前做了去重处理,不会出现重复的选项
- 名称搜索支持不区分大小写的模糊匹配
内容的提问来源于stack exchange,提问作者Shubham Sanchela
相关产品推荐
相关产品推荐

