React实现JSON表格多列独立过滤功能求助(无第三方库)
问题描述
我有一个包含如下对象的JSON数据:
const obj = [ {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"} ];
我需要把这些数据展示在表格中,实现多列独立过滤功能:每个输入框仅过滤对应列(比如Class输入框只检索class列),过滤结果实时更新到表格。
我用React和JavaScript开发,不使用第三方库,但当前过滤逻辑有问题:每次搜索时都会基于已过滤的结果重新检索,导致过滤异常。当前代码如下:
const [value, setValue] = useState({ lastname: '', class: '', firstname: '', }); const handleSubmit = e => { const searchValue = { ...value, [e.target.name]: e.target.value }; setValue(searchValue); setCopyList( copyList.filter(item => item[e.target.name].includes(e.target.value)) ); };
卡在这个问题上很久了,尤其是useState Hook的使用部分,希望得到解决。
解决方案
核心问题是每次过滤都基于已过滤后的copyList,而非原始数据,导致多次过滤后数据被反复裁剪,无法回到初始状态。另外,输入框name属性需和数据对象字段名对应(比如数据里是fname,但状态里是firstname,需统一)。
步骤1:保存原始数据,作为过滤基准
将原始数据作为常量存储,永远不要直接修改它,所有过滤操作都基于这份数据:
// 原始数据,过滤的基准数据源 const originalData = [ {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"}, {fname:"abhi", age:5, class:"ten", lanme:"kumar"} ]; const [filteredData, setFilteredData] = useState(originalData); // 过滤条件,字段名和原始数据统一 const [filters, setFilters] = useState({ fname: '', class: '', lanme: '' });
步骤2:编写多条件联合过滤逻辑
每次输入变化时,基于原始数据同时应用所有列的过滤条件,而非仅处理当前输入列:
const handleFilterChange = (e) => { const { name, value } = e.target; // 更新当前列的过滤值 const newFilters = { ...filters, [name]: value.toLowerCase() // 转小写实现不区分大小写过滤(可选) }; setFilters(newFilters); // 基于原始数据,应用所有过滤条件 const result = originalData.filter(item => { return ( item.fname.toLowerCase().includes(newFilters.fname) && item.class.toLowerCase().includes(newFilters.class) && item.lanme.toLowerCase().includes(newFilters.lanme) ); }); setFilteredData(result); };
步骤3:对应表格与输入框结构
确保输入框name属性和原始数据字段完全一致,示例结构如下:
<table> <thead> <tr> <th>First Name</th> <th>Class</th> <th>Last Name</th> </tr> <tr> <td> <input type="text" name="fname" value={filters.fname} onChange={handleFilterChange} placeholder="Filter first name" /> </td> <td> <input type="text" name="class" value={filters.class} onChange={handleFilterChange} placeholder="Filter class" /> </td> <td> <input type="text" name="lanme" value={filters.lanme} onChange={handleFilterChange} placeholder="Filter last name" /> </td> </tr> </thead> <tbody> {filteredData.map((item, index) => ( <tr key={index}> <td>{item.fname}</td> <td>{item.class}</td> <td>{item.lanme}</td> </tr> ))} </tbody> </table>
关键要点
- 始终基于原始数据执行过滤操作,避免因反复过滤已裁剪数据导致的异常。
- 所有过滤条件同时生效,实现多列独立过滤且结果叠加的效果。
- 用
filters统一管理所有列的过滤值,filteredData仅存储最终结果,状态职责清晰。
内容的提问来源于stack exchange,提问作者user20216157
相关产品推荐
相关产品推荐

