如何实现Ant Design Table点击上下箭头调整行排序功能?
Ant Design Table 行顺序调整(上移/下移)实现方案
核心逻辑
Ant Design Table 基于数组渲染行,调整行顺序本质是修改数组元素的位置后重新渲染。只需三步实现:添加操作列、编写数组元素交换逻辑、绑定事件。
分步实现
1. 添加操作列
在你的列配置数组中新增一列,用于放置上下箭头按钮:
import { UpOutlined, DownOutlined } from '@ant-design/icons'; import { Button } from 'antd'; // 新增的操作列配置 { title: '调整顺序', align: 'center', width: 100, render: (text, record, rowIndex) => ( <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}> <Button type="text" icon={<UpOutlined />} disabled={rowIndex === 0} // 第一行禁用上移 onClick={() => handleRowUp(rowIndex)} /> <Button type="text" icon={<DownOutlined />} disabled={rowIndex === tableData.length - 1} // 最后一行禁用下移 onClick={() => handleRowDown(rowIndex)} /> </div> ), }
2. 编写上移/下移逻辑
假设你的表格数据存在状态 tableData 中,编写以下两个处理函数:
import { useState } from 'react'; // 假设你的数据状态定义 const [tableData, setTableData] = useState(/* 初始数据数组 */); // 对应你现有代码中的选中行索引状态 const [selectedIndex, setSelectedIndex] = useState(-1); // 行上移函数 const handleRowUp = (rowIndex) => { if (rowIndex === 0) return; // 复制原数组,避免直接修改状态 const newData = [...tableData]; // 交换当前行与上一行的位置 [newData[rowIndex], newData[rowIndex - 1]] = [newData[rowIndex - 1], newData[rowIndex]]; setTableData(newData); // 同步更新选中行索引(如果涉及选中状态) if (selectedIndex === rowIndex) { setSelectedIndex(rowIndex - 1); } else if (selectedIndex === rowIndex - 1) { setSelectedIndex(rowIndex); } }; // 行下移函数 const handleRowDown = (rowIndex) => { if (rowIndex === tableData.length - 1) return; const newData = [...tableData]; [newData[rowIndex], newData[rowIndex + 1]] = [newData[rowIndex + 1], newData[rowIndex]]; setTableData(newData); // 同步更新选中行索引 if (selectedIndex === rowIndex) { setSelectedIndex(rowIndex + 1); } else if (selectedIndex === rowIndex + 1) { setSelectedIndex(rowIndex); } };
3. 整合现有代码
将新增的操作列加入你的列配置数组,确保Table组件的dataSource绑定tableData,原有的onRow逻辑无需修改,二者完全独立:
<Table dataSource={tableData} columns={[ // 你的其他列配置... { /* 上面新增的操作列 */ }, { title: '착유시간(s/회)', width: '15px', align: 'center', dataIndex: 'milkingtmmPerStr', sortDirections: ['descend', 'ascend', 'descend'], sorter: (a, b) => String(a.milkingtmmPerStr).localeCompare(b.milkingtmmPerStr), render(text, record) { return { props: { style: { background: text < '00:05:00' ? 'white' : 'white' }, }, children: <div>{text}</div>, }; }, }, ]} onRow={onRow} // 保留原有的onRow逻辑 rowKey="aniSeq" // 必须设置唯一的rowKey,避免渲染异常 />
注意事项
- rowKey 必填:必须为Table设置
rowKey(建议用数据中的唯一标识,比如你的aniSeq),否则移动行后可能出现组件复用异常。 - 后端同步:如果需要持久化顺序,移动完成后需调用接口将新的顺序提交到后端。
- 分页场景:上述逻辑仅适用于无分页或当前页内的行移动,若有分页,需额外处理跨页移动的业务逻辑。
- 状态同步:如果你的页面有其他依赖表格数据的状态(比如你代码中的
aniSeqSel等),移动后需根据业务需求判断是否需要同步更新这些状态。
内容的提问来源于stack exchange,提问作者Joseph Park
相关产品推荐
相关产品推荐

