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

React中使用react-beautiful-dnd实现表格行拖拽后如何保存状态?

解决方案

你当前无法保存拖拽后状态的核心原因有三点:

  • 表格行数据完全硬编码在JSX结构中,没有维护在组件状态里,拖拽结束后没有可更新的数据源
  • 没有给DragDropContext组件绑定必须的onDragEnd回调,这个回调是拖拽动作结束后触发状态更新的唯一入口
  • 现有代码中Draggable的index属性从1开始计数,不符合库的规范,会导致重排逻辑计算错误

修改后的完整可运行代码如下:

import { Component } from 'react';
import React from 'react';
import './App.css';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

class App extends Component
{
  // 把表格数据维护到state中
  state = {
    tableData: [
      { id: '1', no: 1, firstName: 'Mark', lastName: 'Otto', account: '@mdo' },
      { id: '2', no: 2, firstName: 'Jacob', lastName: 'Thornton', account: '@fat' },
      { id: '3', no: 3, firstName: 'Larry the Bird', lastName: '', account: '@twitter' },
    ]
  }

  // 拖拽结束后的处理逻辑
  handleDragEnd = (result) => {
    // 没有目标放置位置时直接返回
    if (!result.destination) return;
    const sourceIndex = result.source.index;
    const destIndex = result.destination.index;
    // 拖拽前后位置没有变化直接返回
    if (sourceIndex === destIndex) return;

    // 复制原数组避免直接修改state
    const newTableData = Array.from(this.state.tableData);
    // 取出被拖拽的元素
    const draggedItem = newTableData.splice(sourceIndex, 1)[0];
    // 把拖拽元素插入到目标位置
    newTableData.splice(destIndex, 0, draggedItem);
    // 更新state触发重渲染,就会显示最新的顺序
    this.setState({ tableData: newTableData });
  }

  drawTable = () => {
    return (
    <div>
      {/* 绑定onDragEnd回调 */}
      <DragDropContext onDragEnd={this.handleDragEnd}>
      <Droppable droppableId="Table">
        {(provided) => (
    <table {...provided.droppableProps} ref={provided.innerRef}>
      {/* 遍历state数据渲染行,不要硬编码 */}
      {this.state.tableData.map((item, index) => (
        <Draggable key={item.id} draggableId={item.id} index={index}>
          {(provided) => (
            <tr ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
              <td>{item.no}</td>
              <td>{item.firstName}</td>
              <td>{item.lastName}</td>
              <td>{item.account}</td>
            </tr>
          )}
        </Draggable>
      ))}
     {provided.placeholder} 
    </table>
    )}
    </Droppable>
    </DragDropContext>
  </div>
   
  );
  
  }


render = () => {

    return (
      <div>
        {this.drawTable()}
      </div>
    );

  }
}

export default App;

修改后拖拽结束后新的行顺序会自动保存在组件state中,如果需要持久化存储,直接在handleDragEnd方法中拿到最新的newTableData调用后端接口保存即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:15:03