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

React实现REST API用户列表多字段筛选及列显示控制问题

解决方案

1. 动态选择筛选字段

首先补充状态管理和筛选逻辑,实现基于用户选择字段的筛选功能:

步骤1:添加筛选字段状态

在App组件中新增状态跟踪选中的筛选字段:

const [selectedFilter, setSelectedFilter] = useState("");

步骤2:实现字段选择事件

定义更新选中字段的处理函数:

const changeSelectedFilter = (e) => {
  setSelectedFilter(e.target.value);
};

步骤3:修改筛选函数

更新search函数,根据选中字段执行筛选;选择"All"时返回全部用户(或可选匹配所有字段):

const search = (data) => {
  // 查询为空时直接返回全部用户
  if (!query) return data;
  
  // 选择"All"时,匹配用户对象的所有字符串字段
  if (selectedFilter === "") {
    return data.filter(item => 
      Object.values(item).some(value => 
        typeof value === 'string' && value.toLowerCase().includes(query)
      )
    );
  }
  
  // 根据选中的指定字段筛选
  return data.filter(item => 
    item[selectedFilter]?.toLowerCase().includes(query)
  );
};

2. 控制列表列的显示与隐藏

通过状态管理列的可见性,实现动态切换:

步骤1:添加列可见性状态

定义初始所有列都可见的状态:

const [visibleColumns, setVisibleColumns] = useState({
  name: true,
  username: true,
  email: true,
  phone: true
});

步骤2:实现列切换函数

创建切换列可见性的函数:

const toggleColumn = (column) => {
  setVisibleColumns(prevState => ({
    ...prevState,
    [column]: !prevState[column]
  }));
};

步骤3:渲染列控制选项

在App组件中添加复选框,让用户选择显示/隐藏列:

<div className="column-controls">
  <label>
    <input 
      type="checkbox" 
      checked={visibleColumns.name} 
      onChange={() => toggleColumn('name')} 
    />
    姓名
  </label>
  <label>
    <input 
      type="checkbox" 
      checked={visibleColumns.username} 
      onChange={() => toggleColumn('username')} 
    />
    用户名
  </label>
  <label>
    <input 
      type="checkbox" 
      checked={visibleColumns.email} 
      onChange={() => toggleColumn('email')} 
    />
    邮箱
  </label>
  <label>
    <input 
      type="checkbox" 
      checked={visibleColumns.phone} 
      onChange={() => toggleColumn('phone')} 
    />
    电话
  </label>
</div>

步骤4:修改UserTable组件

将visibleColumns传递给UserTable,根据状态渲染对应列:

// App.js中传递props
<UserTable 
  data={search(users)} 
  visibleColumns={visibleColumns} 
/>

// UserTable组件示例
function UserTable({ data, visibleColumns }) {
  return (
    <table>
      <thead>
        <tr>
          {visibleColumns.name && <th>姓名</th>}
          {visibleColumns.username && <th>用户名</th>}
          {visibleColumns.email && <th>邮箱</th>}
          {visibleColumns.phone && <th>电话</th>}
        </tr>
      </thead>
      <tbody>
        {data.map(user => (
          <tr key={user.id}>
            {visibleColumns.name && <td>{user.name}</td>}
            {visibleColumns.username && <td>{user.username}</td>}
            {visibleColumns.email && <td>{user.email}</td>}
            {visibleColumns.phone && <td>{user.phone}</td>}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

完整App.js代码示例

import { useState, useEffect } from 'react';
import UserTable from './UserTable';

function App() {
  const [users, setUsers] = useState([]);
  const [query, setQuery] = useState("");
  const [selectedFilter, setSelectedFilter] = useState("");
  const [visibleColumns, setVisibleColumns] = useState({
    name: true,
    username: true,
    email: true,
    phone: true
  });

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await response.json();
      setUsers(data);
    } catch (error) {
      console.log("ERROR:" + error);
    }
  };

  const changeSelectedFilter = (e) => {
    setSelectedFilter(e.target.value);
  };

  const toggleColumn = (column) => {
    setVisibleColumns(prevState => ({
      ...prevState,
      [column]: !prevState[column]
    }));
  };

  const search = (data) => {
    if (!query) return data;
    if (selectedFilter === "") {
      return data.filter(item => 
        Object.values(item).some(value => 
          typeof value === 'string' && value.toLowerCase().includes(query)
        )
      );
    }
    return data.filter(item => 
      item[selectedFilter]?.toLowerCase().includes(query)
    );
  };

  return (
    <div className="App">
      <h1>用户列表</h1>

      <select className='select' onChange={changeSelectedFilter}>
        <option value="">All</option>
        <option value="name">Name</option>
        <option value="username">Username</option>
        <option value="email">Email</option>
        <option value="phone">Phone</option>
      </select>

      <input 
        type="text"
        placeholder='Search...'
        className='search'
        onChange={e => setQuery(e.target.value.toLowerCase())}
      />

      <div className="column-controls">
        <label>
          <input 
            type="checkbox" 
            checked={visibleColumns.name} 
            onChange={() => toggleColumn('name')} 
          />
          姓名
        </label>
        <label>
          <input 
            type="checkbox" 
            checked={visibleColumns.username} 
            onChange={() => toggleColumn('username')} 
          />
          用户名
        </label>
        <label>
          <input 
            type="checkbox" 
            checked={visibleColumns.email} 
            onChange={() => toggleColumn('email')} 
          />
          邮箱
        </label>
        <label>
          <input 
            type="checkbox" 
            checked={visibleColumns.phone} 
            onChange={() => toggleColumn('phone')} 
          />
          电话
        </label>
      </div>

      <UserTable 
        data={search(users)} 
        visibleColumns={visibleColumns} 
      />
    </div>
  );
}

export default App;

内容的提问来源于stack exchange,提问作者Adrián Ruiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:16:13