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

React中带搜索栏的表格删除行功能异常问题求助

React表格搜索后删除功能异常修复

问题现象

开发包含删除按钮和搜索框的React表格时,未搜索状态下删除功能正常,但搜索后点击删除按钮只会删除原数组的第一行,而非当前展示行。

问题根源

  1. 索引不匹配:表格组件使用map的索引作为删除标识,但搜索后表格展示的是过滤后的数组,其索引与原数据数组的索引不一致。
  2. 删除逻辑依赖原数组索引:删除函数基于原数组的索引过滤数据,导致搜索后传递的索引对应到原数组中是错误的条目。
  3. 表格未渲染搜索结果:原代码中表格的bodyData直接传递原数组newUserArr,未使用过滤后的searchedArray,导致搜索后界面未更新展示结果。

解决方案

步骤1:为数据添加唯一标识

确保每个用户对象拥有唯一id(如果mock数据中没有,初始化时补充):

// Home组件中修改useState初始化
const [newUserArr, setNewUserArr] = useState(
  userArr.map((user, idx) => ({ ...user, id: idx + 1 })) // 生成唯一id
);

步骤2:修改表格组件的删除逻辑

将删除按钮的参数从索引改为用户的唯一id:

// Table组件的buildTableItems函数
return bodyData.map((item) => ( // 可以去掉index参数,不需要了
  <tr className="data-tr" key={item.id}> {/* 添加key属性,优化React渲染 */}
    <td>{item.name}</td>
    <td>{item.email}</td>
    <td>{item.occupation}</td>
    <td>{formatDate(item.birthday)}</td>
    <td>
      <button className="delete-button" onClick={() => removeItem(item.id)}>
        Delete
      </button>
    </td>
  </tr>
));

步骤3:修改Home组件的删除函数

改为根据用户id过滤原数组,而非索引:

// Home组件的deleteData函数
const deleteData = (userId) => {
  const restOfDataArray = newUserArr.filter(
    (element) => element.id !== userId
  );
  setNewUserArr(restOfDataArray);
};

步骤4:让表格渲染搜索结果

将Table组件的bodyData改为传递过滤后的searchedArray:

// Home组件的Table调用
<Table
  type="user"
  headerData={headerUser}
  bodyData={searchedArray} // 替换为搜索后的数组
  removeItem={(userId) => deleteData(userId)}
/>

完整修改后代码

Table组件

import { formatDate } from "../../utils/formatDate";
import "./table.css";

function Table(props) {
  const { headerData, bodyData, removeItem} = props;

  const buildTableItems = () => {
    return bodyData.map((item) => (
      <tr className="data-tr" key={item.id}>
        <td>{item.name}</td>
        <td>{item.email}</td>
        <td>{item.occupation}</td>
        <td>{formatDate(item.birthday)}</td>
        <td>
          <button className="delete-button" onClick={() => removeItem(item.id)}>
            Delete
          </button>
        </td>
      </tr>
    ));
  };
  return (
    <div className="user-data">
      <table className="user-table">
        <thead>
          <tr className="data-th">
            {headerData.map((headerTable, idx) => (
              <th key={idx}>{headerTable}</th> {/* 添加key */}
            ))}
          </tr>
        </thead>
        <tbody>{buildTableItems()}</tbody>
      </table>
    </div>
  );
}

export default Table;

Home组件

import "./Home.css";
import React, { useState } from "react";
import Header from "../components/Header/Header";
import Table from "../components/Table/Table";
import AddData from "../components/AddData/AddData";
import SearchBar from "../components/SearchBar/SearchBar";
import { userArr } from "../mock/users";

const Home = () => {
  const headerUser = ["Name", "Email", "Occupation", "Birthday"];
  // 初始化时为每个用户添加唯一id
  const [newUserArr, setNewUserArr] = useState(
    userArr.map((user, idx) => ({ ...user, id: idx + 1 }))
  );
  const [searchedItem, setSearchedItem] = useState("");

  const searchedArray = newUserArr.filter((item) => {
    return item.name.toLowerCase().includes(searchedItem.toLowerCase());
  });

  const onSearch = (e) => {
    setSearchedItem(e);
  };

  const addDataToArr = (form) => {
    // 新增数据时也添加唯一id
    setNewUserArr([...newUserArr, { ...form, id: newUserArr.length + 1 }]);
  };

  const deleteData = (userId) => {
    const restOfDataArray = newUserArr.filter(
      (element) => element.id !== userId
    );
    setNewUserArr(restOfDataArray);
  };

  return (
    <>
      <Header />
      <SearchBar searchedData={searchedItem} onSearch={onSearch} />
      <Table
        type="user"
        headerData={headerUser}
        bodyData={searchedArray}
        removeItem={deleteData} // 简化传递
      />
      <AddData saveData={addDataToArr} />
    </>
  );
};

export default Home;

内容的提问来源于stack exchange,提问作者Dênis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:57:18