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
相关产品推荐
相关产品推荐

