You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:05:21