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

ReactJs类组件(非Hooks)如何实现点击按钮仅更新当前行状态

问题修复方案

核心问题原因

原代码使用全局单一clicked状态控制所有行的按钮显示逻辑,只要状态变更所有行都会同步响应,才会出现点击任意行编辑按钮所有行都切换状态的问题。同时原代码直接操作DOM设置contenteditable属性,不符合React数据驱动视图的设计规范,容易出现状态和视图不同步的问题。

具体优化思路

  • 将表格行数据抽离为结构化数组存入state,每条数据配置唯一id,新增isEditing字段单独控制当前行的编辑状态
  • 编辑、更新、取消操作均传入目标行的id,仅修改对应行的isEditing状态,不影响其他行数据
  • 渲染表格时使用map遍历行数据,每行根据自身的isEditing值渲染对应按钮,同时直接通过状态控制单元格的contentEditable属性

完整修改后代码

import React from 'react';
    
class GridSample extends React.Component {
  constructor() {
    super();
    this.state = {
      // 结构化存储表格数据,每条数据单独控制编辑状态
      tableData: [
        {id: 1, firstname: 'Jill', lastname: 'Smith', age: 50, isEditing: false},
        {id: 2, firstname: 'Eve', lastname: 'Jackson', age: 94, isEditing: false},
        {id: 3, firstname: 'John', lastname: 'Doe', age: 80, isEditing: false},
      ]
    };
    this.handleOnedit = this.handleOnedit.bind(this);
    this.handleCancel = this.handleCancel.bind(this);
    this.handleUpdate = this.handleUpdate.bind(this);
    this.handleOndelete = this.handleOndelete.bind(this);
  }
  // 传入行id,仅修改目标行的编辑状态
  handleOnedit = (id) => {
    this.setState(prevState => ({
      tableData: prevState.tableData.map(item => {
        if(item.id === id) {
          return {...item, isEditing: true}
        }
        return item
      })
    }))
  };

  handleOndelete() {
    alert('this is delete button');
  }

  // 取消编辑,重置目标行状态
  handleCancel(id) {
    this.setState(prevState => ({
      tableData: prevState.tableData.map(item => {
        if(item.id === id) {
          return {...item, isEditing: false}
        }
        return item
      })
    }))
  }

  // 更新完成后重置目标行状态
  handleUpdate(id) {
    this.setState(prevState => ({
      tableData: prevState.tableData.map(item => {
        if(item.id === id) {
          return {...item, isEditing: false}
        }
        return item
      })
    }));
    // 此处可补充提交更新后数据的逻辑
  }

  render() {
    console.clear();
    return (
      <div>
        <table>
          <thead>
            <tr>
              <th>Firstname</th>
              <th>Lastname</th>
              <th>Age</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {/* 遍历数据渲染行,每行用自身状态控制显示 */}
            {this.state.tableData.map(row => (
              <tr key={row.id}>
                <td contentEditable={row.isEditing}>{row.firstname}</td>
                <td contentEditable={row.isEditing}>{row.lastname}</td>
                <td contentEditable={row.isEditing}>{row.age}</td>
                <td>
                  {!row.isEditing ? (
                    <input type="button" value="Edit" onClick={() => this.handleOnedit(row.id)} />
                  ) : (
                    <input
                      type="button"
                      value="Update"
                      onClick={() => this.handleUpdate(row.id)}
                    />
                  )}
                  {row.isEditing ? (
                    <input
                      type="button"
                      value="Cancel"
                      onClick={() => this.handleCancel(row.id)}
                    />
                  ) : (
                    <input
                      type="button"
                      value="Delete"
                      onClick={this.handleOndelete}
                    />
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

export default GridSample;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:09:04