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

React中如何通过Navbar实现表格选项式过滤?代码修正请求

修复多条件筛选功能的React组件代码

以下是针对多条件筛选功能的完整修正方案,解决了原代码中状态传递、事件绑定和过滤逻辑的问题:


1. CollegeNavbar组件修正

修改要点:

  • 修复react-select的onChange事件,正确接收选中选项
  • 修正下拉选项的value字段,使其对应实际筛选值
  • 移除无用的filter状态和冗余事件,改为收集三个筛选条件
  • 点击搜索时将筛选条件传递给父组件
import Button from "react-bootstrap/Button";
import React, { useState } from "react";
import Select from "react-select";
import { Col, Row } from "reactstrap";

function CollegeNavbar(props) {
  // 维护三个筛选条件的状态
  const [selectedCollege, setSelectedCollege] = useState(null);
  const [selectedBranch, setSelectedBranch] = useState(null);
  const [selectedYear, setSelectedYear] = useState(null);

  // 修正选项的value为实际筛选值
  const collegeOptions = [
    { value: "SCOE", label: "SCOE" },
    { value: "SKN", label: "SKN" },
    { value: "NBNSCOE", label: "NBNSCOE" },
  ];
  const branchOptions = [
    { value: "CS", label: "CS" },
    { value: "IT", label: "IT" },
    { value: "ENTC", label: "ENTC" },
    { value: "MECHANICAL", label: "MECHANICAL" },
    { value: "CIVIL", label: "CIVIL" },
    { value: "CHEMICAL", label: "CHEMICAL" },
    { value: "BIO-TECH", label: "BIO-TECH" },
    { value: "PRODUCTION", label: "PRODUCTION" },
  ];
  const yearOptions = [
    { value: "FE", label: "FE" },
    { value: "SE", label: "SE" },
    { value: "TE", label: "TE" },
    { value: "BE", label: "BE" },
  ];

  // 点击搜索时传递筛选条件给父组件
  const handleSearch = () => {
    props.onFilter({
      college: selectedCollege?.value || "",
      branch: selectedBranch?.value || "",
      year: selectedYear?.value || "",
    });
  };

  return (
    <>
      <Row className="px-3">
        <Col className="col-12 col-sm-12 col-lg-11 text-center my-2 px-0 align-self-center">
          <Row className="mx-0">
            <Col className="col-12 col-sm-12 col-lg-4 pr-3">
              <div id="collegename" className="dropdown-container">
                <Select
                  options={collegeOptions}
                  placeholder="College Name"
                  value={selectedCollege}
                  onChange={(selected) => setSelectedCollege(selected)}
                  isSearchable={true}
                  isClearable
                />
              </div>
            </Col>
            <Col className="col-12 col-sm-12 col-lg-4 px-3">
              <div id="branchname" className="dropdown-container">
                <Select
                  options={branchOptions}
                  placeholder="Branch Name"
                  value={selectedBranch}
                  onChange={(selected) => setSelectedBranch(selected)}
                  isSearchable={true}
                  isClearable
                />
              </div>
            </Col>
            <Col className="col-12 col-sm-12 col-lg-4 px-3">
              <div id="curryear" className="dropdown-container">
                <Select
                  options={yearOptions}
                  placeholder="Current Year"
                  value={selectedYear}
                  onChange={(selected) => setSelectedYear(selected)}
                  isSearchable={true}
                  isClearable
                />
              </div>
            </Col>
          </Row>
        </Col>
        <Col className="col-12 col-sm-12 col-lg-1 text-center my-2 px-0">
          <Button
            onClick={handleSearch}
            variant="outline-success"
            size="lg"
          >
            Search
          </Button>
        </Col>
      </Row>
    </>
  );
}

export default CollegeNavbar;

2. AdminCollegeStudentTable组件修正

修改要点:

  • 移除冗余的students状态,改为维护原始数据和过滤后数据两个状态
  • 接收父组件传递的筛选条件,通过useEffect自动处理过滤
  • 修正删除、撤销操作后的状态同步逻辑
  • 移除Table组件上无效的onChange事件
  • 过滤逻辑改为多条件匹配,未选择的条件不参与过滤
import Table from "react-bootstrap/Table";
import axios from "axios";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom/cjs/react-router-dom.min";

function AdminCollegeStudentTable(props) {
  const [originalData, setOriginalData] = useState([]); // 保存原始数据
  const [filteredData, setFilteredData] = useState([]); // 过滤后的数据
  const [deletedRecords, setDeletedRecords] = useState([]);
  const [lastAction, setLastAction] = useState("");
  const [sortOrder, setSortOrder] = useState("asc");

  // 加载原始数据
  useEffect(() => {
    axios.get("http://localhost:3006/StudentList")
      .then((response) => {
        setOriginalData(response.data);
        setFilteredData(response.data);
      });
  }, []);

  // 根据筛选条件自动过滤数据
  useEffect(() => {
    const { college, branch, year } = props.filters;
    let result = [...originalData];

    if (college) {
      result = result.filter(student => 
        student.college.toLowerCase() === college.toLowerCase()
      );
    }
    if (branch) {
      result = result.filter(student => 
        student.branch.toLowerCase() === branch.toLowerCase()
      );
    }
    if (year) {
      result = result.filter(student => 
        student.year.toLowerCase() === year.toLowerCase()
      );
    }

    setFilteredData(result);
  }, [props.filters, originalData]);

  const handleDelete = (id) => {
    const confirmation = window.confirm("Are you sure you want to delete this record?");
    if (confirmation) {
      const deletedRecord = originalData.find(student => student.id === id);
      axios.delete(`http://localhost:3006/StudentList/${id}`).then(() => {
        const updatedOriginal = originalData.filter(student => student.id !== id);
        setOriginalData(updatedOriginal);
        setDeletedRecords([...deletedRecords, deletedRecord]);
        setLastAction("delete");
        alert("Record deleted successfully! Click Undo button to undo the delete operation.");
      });
    }
  };

  const handleUndo = () => {
    if (lastAction === "delete") {
      const restoredRecord = deletedRecords[deletedRecords.length - 1];
      axios.post("http://localhost:3006/StudentList", restoredRecord)
        .then(() => {
          setOriginalData([...originalData, restoredRecord]);
          setDeletedRecords(deletedRecords.slice(0, -1));
          setLastAction("undo");
        });
    } else if (lastAction === "undo") {
      const reDeletedRecord = originalData[originalData.length - 1];
      axios.delete(`http://localhost:3006/StudentList/${reDeletedRecord.id}`)
        .then(() => {
          setOriginalData(originalData.slice(0, -1));
          setDeletedRecords([...deletedRecords, reDeletedRecord]);
          setLastAction("delete");
        });
    }
  };

  const handleSort = (field) => {
    const sortedData = [...filteredData].sort((a, b) => {
      if (sortOrder === "asc") {
        return a[field] < b[field] ? -1 : 1;
      } else {
        return b[field] < a[field] ? -1 : 1;
      }
    });

    setFilteredData(sortedData);
    setSortOrder(sortOrder === "asc" ? "desc" : "asc");
  };

  return (
    <>
      <Link
        onClick={handleUndo}
        className="btn btn-info mb-3"
        disabled={originalData.length === 0 && deletedRecords.length === 0}
      >
        Undo
      </Link>
      <Table striped bordered hover responsive>
        <thead>
          <tr>
            <th onClick={() => handleSort("id")}>Sr.No</th>
            <th onClick={() => handleSort("name")}>Name</th>
            <th onClick={() => handleSort("college")}>College name</th>
            <th onClick={() => handleSort("branch")}>Branch name</th>
            <th onClick={() => handleSort("year")}>Year</th>
            <th>Profile</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {filteredData.map((student) => (
            <tr key={student.id}>
              <td>{student.id}</td>
              <td>{student.name}</td>
              <td>{student.college}</td>
              <td>{student.branch}</td>
              <td>{student.year}</td>
              <td>
                <Link
                  to={`/student/${student.id}`}
                  className="btn btn-primary sm"
                >
                  View Profile
                </Link>
              </td>
              <td>
                <Link
                  onClick={() => handleDelete(student.id)}
                  className="btn btn-danger sm"
                >
                  Delete
                </Link>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </>
  );
}

export default AdminCollegeStudentTable;

3. AdminCollegeStudentList组件修正

修改要点:

  • 维护多条件筛选的状态对象
  • 传递回调给Navbar以更新筛选条件
  • 将筛选条件传递给Table组件
import React, { useState } from "react";
import CollegeNavbar from "components/Navbars/CollegeNavbar";
import AdminCollegeStudentTable from "components/Tables/AdminCollegeStudentTable";

// reactstrap components
import { Card, CardHeader, CardBody, Row, Col } from "reactstrap";

function AdminCollegeStudents() {
  // 维护筛选条件状态
  const [filters, setFilters] = useState({
    college: "",
    branch: "",
    year: ""
  });

  // 接收Navbar传递的筛选条件并更新状态
  const handleFilter = (newFilters) => {
    setFilters(newFilters);
  };

  return (
    <>
      <div className="content">
        <Row>
          <Col>
            <div className="CollegeNav">
              <CollegeNavbar onFilter={handleFilter} />
            </div>
            <Card>
              <CardHeader>
                <h1 className="title">Students</h1>
              </CardHeader>
              <CardBody className="all-icons">
                <AdminCollegeStudentTable filters={filters} />
              </CardBody>
            </Card>
          </Col>
        </Row>
      </div>
    </>
  );
}

export default AdminCollegeStudents;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:39:54