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

React下拉框筛选实现:点击选项后更新表格显示对应数据

React表格筛选功能问题排查

我在React网页里做了一个销售记录表格,想实现用户点击下拉菜单选项后,表格只显示对应销售顾问的数据。试了好几种方法,还花了好几个小时看视频学习,下面是我的代码。我创建了筛选状态,对salesperson数组做了映射,也用了.includes(filterTerm),但就是找不到问题,控制台只显示模糊的错误。我是React新手,肯定有语法或逻辑错误,麻烦帮忙排查下,谢谢。

import React, {useState, useEffect } from 'react';

function ListSalesHistory() {

  const [sales, setSales] = useState([])
  const [salespersons, setSalesPersons] = useState([])

  const [filterTerm, setFilterTerm] = useState("")

  const handleFilterChange = (e) => {
    setFilterTerm(e.target.value);
  }

  const fetchData = async () => {
    const url = 'http://localhost:8090/api/sales/salesperson/';
    const response = await fetch(url);

    if (response.ok) {
      const data = await response.json();
      setSalesPersons(data.salespersons);
    }
  }

  const getData = async () => {
    const response = await fetch('http://localhost:8090/api/sales/');

    if (response.ok) {
      const data = await response.json();
      setSales(data.salesrecord)
    }

  }

  useEffect(()=>{
    getData()
  }, [])

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

  const handleSalesPersonChange = (event) => {
    const value = event.target.value;
    setSalesPersons(value);
}

  return (
    <div>
      <h1>Sales person history</h1>
      <select value={salespersons} onChange={handleSalesPersonChange} required id ="salesperson" name="salesperson" className="form-select form-select-lg form-select-padding-lg mb-3" >
        <option value="" onChange={handleFilterChange}>Choose a sales person</option>
        {salespersons
        .filter((saleperson) => saleperson.name.includes(filterTerm))
        .map(saleperson => {
          return(
            <option key={ saleperson.name } value={ saleperson.name }>
              { saleperson.name }
            </option>
          )
        })}
      </select>
      <table className="table table-striped">
      <thead>
        <tr>
          <th>Sales person</th>
          <th>Customer</th>
          <th>VIN</th>
          <th>Sale price ($)</th>
        </tr>
      </thead>
      <tbody>
        {sales.map(sale => {
          return(
            <tr key={ sale.id }>
              <td>{ sale.sales_person.name }</td>
              <td>{ sale.customer.name }</td>
              <td>{ sale.automobile.vin }</td>
              <td>{ sale.sales_price }</td>
            </tr>
          );
        })}
      </tbody>
    </table>
    </div>

  )
}

export default ListSalesHistory;

错误分析

  • 状态混用:salespersons原本是存储销售顾问列表的数组,你却在handleSalesPersonChange里把它改成了选中的字符串值,导致后续调用.filter、.map时因类型不匹配报错。
  • 筛选逻辑错位:你错误地用filterTerm筛选下拉选项,实际需求是用选中的销售顾问名字筛选表格数据。
  • 事件绑定错误:<option>的onChange无效,下拉框的选择事件应该绑定在<select>上;且你把更新选中值的逻辑错误地修改了列表数组。
  • 缺失表格筛选逻辑:没有对sales数组做筛选,表格始终显示全量数据。

修正后的代码

import React, { useState, useEffect } from 'react';

function ListSalesHistory() {
  const [sales, setSales] = useState([]);
  const [salespersons, setSalesPersons] = useState([]);
  // 新增状态存储选中的销售顾问名字
  const [selectedSalesPerson, setSelectedSalesPerson] = useState("");

  const fetchData = async () => {
    const url = 'http://localhost:8090/api/sales/salesperson/';
    const response = await fetch(url);
    if (response.ok) {
      const data = await response.json();
      setSalesPersons(data.salespersons);
    }
  };

  const getData = async () => {
    const response = await fetch('http://localhost:8090/api/sales/');
    if (response.ok) {
      const data = await response.json();
      setSales(data.salesrecord);
    }
  };

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

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

  // 修改为更新选中的销售顾问名字,而非修改列表数组
  const handleSalesPersonChange = (event) => {
    setSelectedSalesPerson(event.target.value);
  };

  return (
    <div>
      <h1>Sales person history</h1>
      <select 
        value={selectedSalesPerson} 
        onChange={handleSalesPersonChange} 
        required 
        id="salesperson" 
        name="salesperson" 
        className="form-select form-select-lg form-select-padding-lg mb-3"
      >
        <option value="">Choose a sales person</option>
        {/* 直接映射销售顾问列表,无需筛选选项 */}
        {salespersons.map(saleperson => (
          <option key={saleperson.name} value={saleperson.name}>
            {saleperson.name}
          </option>
        ))}
      </select>
      <table className="table table-striped">
        <thead>
          <tr>
            <th>Sales person</th>
            <th>Customer</th>
            <th>VIN</th>
            <th>Sale price ($)</th>
          </tr>
        </thead>
        <tbody>
          {/* 根据选中值筛选销售记录 */}
          {sales
            .filter(sale => {
              if (!selectedSalesPerson) return true; // 未选中时显示全部
              return sale.sales_person.name === selectedSalesPerson;
            })
            .map(sale => (
              <tr key={sale.id}>
                <td>{sale.sales_person.name}</td>
                <td>{sale.customer.name}</td>
                <td>{sale.automobile.vin}</td>
                <td>{sale.sales_price}</td>
              </tr>
            ))}
        </tbody>
      </table>
    </div>
  );
}

export default ListSalesHistory;

关键修改说明

  1. 新增selectedSalesPerson状态,专门存储下拉框选中的销售顾问名字,和salespersons列表状态彻底分离,避免类型冲突。
  2. 移除无用的filterTerm相关逻辑,下拉选项直接渲染所有销售顾问即可。
  3. 修改handleSalesPersonChange函数,仅更新选中状态,不修改列表数组。
  4. 表格渲染时,通过.filter方法根据selectedSalesPerson筛选销售记录:未选中时显示全部,选中后只显示对应销售顾问的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:15:03