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

ReactJS与Material UI:如何传值至组件实现表格行删除?

解决点击删除按钮总是删除最后一行的问题

看起来你的问题核心是没有把当前行的索引正确传递给删除函数,导致父组件无法定位到要删除的行。另外父组件里还有一处多余的bind调用,可能也会带来混淆,我们一步步来修复:

1. 修复删除按钮的点击事件(核心问题)

在子组件的row函数中,你需要明确把当前行的索引i传递给handleDelete。直接写onClick={handleDelete}会把点击事件对象作为参数传过去,而不是你需要的行索引,这就是为什么总是删错行。

修改row函数里的DeleteIcon部分:

const row = (props, i, handleDelete) => <TableRow key={`thr-${i}`}>
  <TableRowColumn>
    {props.nameTask}
  </TableRowColumn>
  <TableRowColumn className="IconButton">
    <IconButton>
      {/* 用箭头函数包裹,传递当前行的索引i */}
      <DeleteIcon onClick={() => handleDelete(i)}/>
    </IconButton>
  </TableRowColumn>
</TableRow>;

或者你也可以用bind来传递参数:

<DeleteIcon onClick={handleDelete.bind(null, i)}/>

2. 移除父组件中多余的bind调用

你的handleDelete已经用箭头函数定义了,它会自动绑定当前组件的this,所以constructor里的this.handleDelete = this.handleDelete.bind(this);是多余的,直接删掉即可:

修改后的父组件构造函数:

constructor(props) {
  super(props);
  this.state = { data: [] };
  // 删掉这行:this.handleDelete = this.handleDelete.bind(this);
}

完整修改后的代码

父组件 Home.js

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = { data: [] };
  }

  // Delete row from table
  handleDelete = (index) => {
    // 这里用扩展运算符创建新数组也可以,更直观
    const newData = [...this.state.data];
    newData.splice(index, 1);
    this.setState({ data: newData });
  }

  render() {
    return (
      <div>
        <TableTasks 
          handleDelete={this.handleDelete} 
          data={this.state.data} 
          header={[{ name: "Task" }, { name: "Delete" }]} 
        />
      </div>
    );
  }
}
export default Home;

子组件 TableTasks.js

const row = (props, i, handleDelete) => <TableRow key={`thr-${i}`}>
  <TableRowColumn>
    {props.nameTask}
  </TableRowColumn>
  <TableRowColumn className="IconButton">
    <IconButton>
      <DeleteIcon onClick={() => handleDelete(i)}/>
    </IconButton>
  </TableRowColumn>
</TableRow>;

export const TableTasks = ({ data, header, handleDelete }) => <Table>
  <TableHeader>
    <TableRow>
      {header.map((x, i) => <TableHeaderColumn key={`thc-${i}`}>
        {x.name}
      </TableHeaderColumn>)}
    </TableRow>
  </TableHeader>
  <TableBody>
    {data.map((x, i) => row(x, i, handleDelete))}
  </TableBody>
</Table>;

为什么原来的代码会删最后一行?

当你直接把handleDelete传给onClick时,点击事件会把Event对象作为第一个参数传给handleDelete,而不是你期望的行索引i。Event对象转换成数字时会变成NaN,splice(NaN, 1)会被当作splice(0, 1)处理,或者在循环闭包的影响下捕获到最后一个索引值,最终导致总是删除错误的行。现在明确传递i之后,就能准确定位要删除的行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:02:44