1. 封装高阶组件
import React from 'react';import 'antd/dist/antd.css';import { DndProvider, DragSource, DropTarget } from 'react-dnd';import { HTML5Backend } from 'react-dnd-html5-backend';// 基于react-dnd实现的可拖拽的Tableclass BodyRow extends React.Component { render() { const { connectDragSource, connectDropTarget, ...restProps } = this.props; const style = { ...restProps.style, cursor: 'move' }; return connectDragSource( connectDropTarget(<tr {...restProps} style={style} />) ); }}const rowSource = { beginDrag(props) { return { index: props.index }; }};const rowTarget = { drop(props, monitor) { const dragIndex = monitor.getItem().index; const hoverIndex = props.index; if (dragIndex === hoverIndex) { return; } // Time to actually perform the action props.dragSort(dragIndex, hoverIndex); monitor.getItem().index = hoverIndex; }};const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({ connectDropTarget: connect.dropTarget(), isOver: monitor.isOver()}))( DragSource('row', rowSource, connect => ({ connectDragSource: connect.dragSource() }))(BodyRow));export default function DraggableTable (SourceTable){ // eslint-disable-next-line react/no-multi-comp return class extends React.Component{ constructor(props){ super(props); } dragableRow = { body: { row: DragableBodyRow } }; render(){ return ( <DndProvider backend={HTML5Backend}> <SourceTable {...this.props} dragableRow={this.dragableRow}/> //关键行,给源组件传入dragableRow属性 </DndProvider> ); } }}
2. 源组件配置属性components,使之可拖拽。例如:
<Table className="list-table" rowKey={(row) => row.id} columns={this.getColumns()} dataSource={this.state.list} pagination={false} croll={{ y: 800 }} components={this.props.dragableRow} //关键行,配置components属性 onRow={(record, index) => ({ index, dragSort: this.dragSort //真正的排序逻辑 })}/>
2. 可拖拽高阶组件的使用,例如:
import TableDragable from '../../components/TableDragable.jsx';import ListTable from './components/ListTable.jsx';
const ListTableDragable = TableDragable(ListTable); //调用高阶组件
...
return <ListTableDragable/>; //新组件的使用