问题描述
在项目中遇到使用antd中Table表格组件既可以拖拽同时也可以展开,相关配置官网上都有,但是在实际使用时出现一个小问题,就是在使用拖拽手柄进行拖拽时,展开行无法收起。这块使用的了react-sortable-hoc
和array-move
,官方示例中使用react-dnd
的拖拽示例没有这方面的问题。
官方示例增加了展开功能
+收起,-展开,可以展开,但是收回不了。
官方默认展开是设置display属性来实现的
同时设置了展开和拖拽之后,不在是通过display来设置了显示隐藏了,而是对节点进行了增加和删除的操作,因此无法收起。。
解决办法
可以通过设置展开expandedRowKeys
的方法来实现展开收起问题,根据onExpandedRowsChange来获取展开的key储存到数组中,expandedRowKeys属性对应一个key数组,这样数组中的key行都会展开,相反数组中不存在的就会收起。
完整组件代码
import React, { useState } from 'react';
import 'antd/dist/antd.css';
import './index.css';
import { MenuOutlined } from '@ant-design/icons';
import { Table } from 'antd';
import { arrayMoveImmutable } from 'array-move';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
const DragHandle = SortableHandle(() => (
<MenuOutlined
style={{
cursor: 'grab',
color: '#999',
}}
/>
));
const columns = [
{
title: 'Sort',
dataIndex: 'sort',
width: 30,
className: 'drag-visible',
render: () => <DragHandle />,
},
{
title: 'Name',
dataIndex: 'name',
className: 'drag-visible',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
index: 0,
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
index: 1,
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
index: 2,
},
];
const SortableItem = SortableElement((props) => <tr {...props} />);
const SortableBody = SortableContainer((props) => <tbody {...props} />);
const App = () => {
const [dataSource, setDataSource] = useState(data);
const [expandedRowKeys, setExpandedRowKeys] = useState([]);
const onSortEnd = ({ oldIndex, newIndex }) => {
if (oldIndex !== newIndex) {
const newData = arrayMoveImmutable(dataSource.slice(), oldIndex, newIndex).filter(
(el) => !!el,
);
console.log('Sorted items: ', newData);
setDataSource(newData);
}
};
const DraggableContainer = (props) => (
<SortableBody
useDragHandle
disableAutoscroll
helperClass="row-dragging"
onSortEnd={onSortEnd}
{...props}
/>
);
const DraggableBodyRow = ({ className, style, ...restProps }) => {
// function findIndex base on Table rowKey props and should always be a right array index
const index = dataSource.findIndex((x) => x.index === restProps['data-row-key']);
return <SortableItem index={index} {...restProps} />;
};
return (
<Table
pagination={false}
dataSource={dataSource}
columns={columns}
rowKey="index"
components={{
body: {
wrapper: DraggableContainer,
row: DraggableBodyRow,
},
}}
expandable={{
expandedRowRender: (record) => "11111",
onExpandedRowsChange: (expandedRows) => {
setExpandedRowKeys([...expandedRows]);
},
expandedRowKeys: expandedRowKeys,
}}
/>
);
};
export default App;