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

如何在React中使用Ant Design Select组件过滤映射数据

如何结合Ant Design Select实现员工数据动态过滤?

我有一份员工测试数据,想要根据Ant Design Select组件的选择结果,动态渲染匹配的员工信息——比如选择选项'java'时,展示所有具备该技能的人员。目前我已经实现了固定条件的数据过滤,但不知道怎么改成结合Select的动态过滤,相关代码如下:

员工测试数据

export const Employees = [
{
    name: "jane",
    skill: 'java',
    rankgrade: '44.2',
    available:'22/01/23',
    doj:'14/04/21'
},
{
    name: "jake",
    skill: 'javascript',
    rankgrade: '43.2',
    available:'22/04/23',
    doj:'14/04/21'
},
{
    name: "kamil",
    skill: 'react',
    rankgrade: '42.2',
    available:'22/11/23',
    doj:'14/04/21'
},
{
    name: "erica",
    skill: 'nexus',
    rankgrade: '38.2',
    available:'22/09/23',
    doj:'14/04/21'
},
{
    name: "jasper",
    skill: 'typescript',
    rankgrade: '47.2',
    available:'22/03/23',
    doj:'14/04/21'
},
{
    name: "jane",
    skill: 'java',
    rankgrade: '44.2',
    available:'22/01/23',
    doj:'14/04/21'
},
{
    name: "jake",
    skill: 'javascript',
    rankgrade: '43.2',
    available:'22/04/23',
    doj:'14/04/21'
},
{
    name: "kamil",
    skill: 'react',
    rankgrade: '42.2',
    available:'22/11/23',
    doj:'14/04/21'
},
{
    name: "erica",
    skill: 'nexus',
    rankgrade: '38.2',
    available:'22/09/23',
    doj:'14/04/21'
},
{
    name: "jasper",
    skill: 'typescript',
    rankgrade: '47.2',
    available:'22/03/23',
    doj:'14/04/21'
},
{
    name: "jane",
    skill: 'java',
    rankgrade: '44.2',
    available:'22/01/23',
    doj:'14/04/21'
},
{
    name: "jake",
    skill: 'javascript',
    rankgrade: '43.2',
    available:'22/04/23',
    doj:'14/04/21'
},
{
    name: "kamil",
    skill: 'react',
    rankgrade: '42.2',
    available:'22/11/23',
    doj:'14/04/21'
},
{
    name: "erica",
    skill: 'nexus',
    rankgrade: '38.2',
    available:'22/09/23',
    doj:'14/04/21'
},
{
    name: "jasper",
    skill: 'typescript',
    rankgrade: '47.2',
    available:'22/03/23',
    doj:'14/04/21'
},
]

当前固定过滤的实现代码

<Space wrap>
    <Select
      defaultValue="Rank/Grade"
      style={{ width: 120 }}
      
      options={[
        { value: '44.2', label: '44.2' },
        { value: '44.4', label: '44.4' },
        { value: '38.2', label: '38.2' },
      ]}
    />
    
     </Space>


 {Employees.filter(employee => employee.skill  === "javascript" && employee.name != "" && employee.rankgrade != "")
         
         .map(filteredPerson => (
         
                <tbody>
                  <tr>
                    <td className="col-lg-2">{filteredPerson.name}</td>
                    <td className="col-lg-2">{filteredPerson.rankgrade}</td>
                    <td className="col-lg-2">{filteredPerson.skill}</td>
                    <td className="col-lg-2">{filteredPerson.available}</td>
                    <td className="col-lg-2">{filteredPerson.doj}</td>
                  </tr>
                </tbody>
                ))}

改造方案(动态过滤实现)

步骤1:添加状态管理

用React的useState钩子保存当前选中的筛选条件(这里以技能筛选为例):

import { useState } from 'react';

// 在组件内部定义状态
const [selectedSkill, setSelectedSkill] = useState('');

步骤2:改造Select组件

绑定value和onChange事件,同时从员工数据中提取唯一技能值生成选项,避免硬编码:

// 提取唯一技能选项
const skillOptions = Array.from(new Set(Employees.map(emp => emp.skill))).map(skill => ({
  value: skill,
  label: skill
}));

// 渲染Select组件
<Space wrap>
  <Select
    placeholder="选择技能"
    style={{ width: 150 }}
    value={selectedSkill}
    onChange={setSelectedSkill}
    options={skillOptions}
  />
</Space>

步骤3:修改过滤逻辑

把固定的"javascript"替换为状态中的selectedSkill,未选择时展示所有员工:

// 动态过滤数据
const filteredEmployees = Employees.filter(employee => {
  // 未选技能则直接保留,否则匹配技能
  const skillMatch = selectedSkill ? employee.skill === selectedSkill : true;
  // 保留非空的姓名和职级
  return skillMatch && employee.name && employee.rankgrade;
});

步骤4:优化表格结构

不能重复渲染<tbody>,所有<tr>要放在同一个<tbody>里:

<table className="table">
  <thead>
    <tr>
      <th className="col-lg-2">姓名</th>
      <th className="col-lg-2">职级</th>
      <th className="col-lg-2">技能</th>
      <th className="col-lg-2">可用日期</th>
      <th className="col-lg-2">入职日期</th>
    </tr>
  </thead>
  <tbody>
    {filteredEmployees.map((emp, index) => (
      <tr key={index}>
        <td className="col-lg-2">{emp.name}</td>
        <td className="col-lg-2">{emp.rankgrade}</td>
        <td className="col-lg-2">{emp.skill}</td>
        <td className="col-lg-2">{emp.available}</td>
        <td className="col-lg-2">{emp.doj}</td>
      </tr>
    ))}
  </tbody>
</table>

完整示例代码

import { useState } from 'react';
import { Select, Space, Table } from 'antd';
import { Employees } from './your-data-file'; // 导入员工数据

const EmployeeFilter = () => {
  const [selectedSkill, setSelectedSkill] = useState('');

  // 提取唯一技能选项
  const skillOptions = Array.from(new Set(Employees.map(emp => emp.skill))).map(skill => ({
    value: skill,
    label: skill
  }));

  // 动态过滤数据
  const filteredEmployees = Employees.filter(employee => {
    const skillMatch = selectedSkill ? employee.skill === selectedSkill : true;
    return skillMatch && employee.name && employee.rankgrade;
  });

  // 表格列配置(用Antd Table更规范)
  const columns = [
    { title: '姓名', dataIndex: 'name', className: 'col-lg-2' },
    { title: '职级', dataIndex: 'rankgrade', className: 'col-lg-2' },
    { title: '技能', dataIndex: 'skill', className: 'col-lg-2' },
    { title: '可用日期', dataIndex: 'available', className: 'col-lg-2' },
    { title: '入职日期', dataIndex: 'doj', className: 'col-lg-2' },
  ];

  return (
    <div>
      <Space wrap style={{ marginBottom: 16 }}>
        <Select
          placeholder="选择技能"
          style={{ width: 150 }}
          value={selectedSkill}
          onChange={setSelectedSkill}
          options={skillOptions}
        />
      </Space>
      <Table
        columns={columns}
        dataSource={filteredEmployees}
        pagination={false}
        bordered
      />
    </div>
  );
};

export default EmployeeFilter;

内容的提问来源于stack exchange,提问作者someone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 23:00:06