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

ReactJS实现表格行内字段可编辑(除指定字段)功能的方案咨询

行内编辑功能实现方案

你可以基于现有React代码做以下改造完成需求:

1. 新增组件状态

首先在组件内新增两个状态变量,用来跟踪编辑状态和临时存储编辑数据:

// 记录当前正在编辑的行索引,null代表无编辑行
const [editingRowIndex, setEditingRowIndex] = useState<number | null>(null)
// 存储当前编辑行的临时修改数据
const [editingForm, setEditingForm] = useState<Partial<Certificate>>({})

2. 改造编辑按钮点击逻辑

修改原来的编辑触发方法,点击编辑时初始化编辑状态:

const handleEdit = (certificate: Certificate, index: number) => {
  setEditingRowIndex(index)
  // 深拷贝当前行数据作为编辑初始值
  setEditingForm({...certificate})
}

3. 新增保存逻辑

编写保存按钮触发的提交逻辑,提交成功后更新列表并退出编辑状态:

const handleSave = async (index: number) => {
  try {
    // 这里调用你原来的保存接口提交editingForm数据
    await saveCertificateApi(editingForm)
    // 更新原response列表对应索引的数据,setResponse为你存储列表的状态更新方法
    const newResponse = [...response]
    newResponse[index] = editingForm as Certificate
    setResponse(newResponse)
    // 退出编辑状态
    setEditingRowIndex(null)
  } catch (err) {
    // 自行适配报错提示逻辑
    console.error('保存失败', err)
  }
}

4. 改造表格渲染逻辑

修改tbody内的行渲染代码,根据编辑状态切换单元格的展示/编辑形式,以及按钮的展示:

<tbody>
{response.map((certificate: Certificate,index:number) => {
  const isEditing = editingRowIndex === index
  return (
    <tr key={certificate.certificateNo}>
      {/* certificateNo字段永远不可编辑 */}
      <td>{certificate.certificateNo}</td>
      <td>
        {isEditing ? 
          <input 
            type="text" 
            value={editingForm.sponser ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, sponser: e.target.value})}
          /> 
          : certificate.sponser
        }
      </td>
      <td>
        {isEditing ? 
          <input 
            type="text" 
            value={editingForm.protoColNo ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, protoColNo: e.target.value})}
          /> 
          : certificate.protoColNo
        }
      </td>
      <td>
        {isEditing ? 
          <input 
            type="date" 
            value={editingForm.startDate ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, startDate: e.target.value})}
          /> 
          : certificate.startDate
        }
      </td>
      <td>
        {isEditing ? 
          <input 
            type="date" 
            value={editingForm.endDate ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, endDate: e.target.value})}
          /> 
          : certificate.endDate
        }
      </td>
      <td>
        {isEditing ? 
          <input 
            type="number" 
            value={editingForm.noOfSubjects ?? 0} 
            onChange={(e) => setEditingForm({...editingForm, noOfSubjects: Number(e.target.value)})}
          /> 
          : certificate.noOfSubjects
        }
      </td>
      <td>
        {isEditing ? 
          <input 
            type="text" 
            value={editingForm.country ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, country: e.target.value})}
          /> 
          : certificate.country
        }
      </td>
      <td>
        {isEditing ? 
          <select 
            value={editingForm.requestStatus ?? ''} 
            onChange={(e) => setEditingForm({...editingForm, requestStatus: e.target.value})}
          >
            {/* 这里替换成你实际的状态选项 */}
            <option value="PENDING">待审核</option>
            <option value="APPROVED">已通过</option>
            <option value="REJECTED">已驳回</option>
          </select>
          : certificate.requestStatus
        }
      </td>
      <td>
        <div className="btn-group mr-2">
          {isEditing ? (
            <button className="btn btn-sm btn-outline-primary" onClick={()=>handleSave(index)}>
              保存
            </button>
            // 如果需要取消按钮可以取消注释下方代码
            /* <button className="btn btn-sm btn-outline-secondary ml-1" onClick={()=>setEditingRowIndex(null)}>
              取消
            </button> */
          ) : (
            <button className="btn btn-sm btn-outline-secondary" onClick={()=>handleEdit(certificate,index)}>
              <i className="bi bi-pencil"></i>
            </button>
          )}
        </div>
      </td>
    </tr>
  )
})}
</tbody>

如果需要适配不同字段的输入类型,比如下拉选择、数字输入等,直接修改对应字段的输入组件即可,逻辑完全通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:24:04