--- order: 13 title: zh-CN: 上传列表拖拽排序 en-US: Drag sorting of uploadList --- ## zh-CN 使用 `itemRender` ,我们可以集成 react-dnd 来实现对上传列表拖拽排序。 ## en-US By using `itemRender`, we can integrate upload with react-dnd to implement drag sorting of uploadList. ```tsx import { UploadOutlined } from '@ant-design/icons'; import { Button, Tooltip, Upload } from 'antd'; import type { UploadFile, UploadProps } from 'antd/es/upload/interface'; import update from 'immutability-helper'; import React, { useCallback, useRef, useState } from 'react'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; const type = 'DragableUploadList'; interface DragableUploadListItemProps { originNode: React.ReactElement>; file: UploadFile; fileList: UploadFile[]; moveRow: (dragIndex: any, hoverIndex: any) => void; } const DragableUploadListItem = ({ originNode, moveRow, file, fileList, }: DragableUploadListItemProps) => { const ref = useRef(null); const index = fileList.indexOf(file); const [{ isOver, dropClassName }, drop] = useDrop({ accept: type, collect: monitor => { const { index: dragIndex } = monitor.getItem() || {}; if (dragIndex === index) { return {}; } return { isOver: monitor.isOver(), dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward', }; }, drop: (item: any) => { moveRow(item.index, index); }, }); const [, drag] = useDrag({ type, item: { index }, collect: monitor => ({ isDragging: monitor.isDragging(), }), }); drop(drag(ref)); const errorNode = {originNode.props.children}; return (
{file.status === 'error' ? errorNode : originNode}
); }; const App: React.FC = () => { const [fileList, setFileList] = useState([ { uid: '-1', name: 'image1.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', }, { uid: '-2', name: 'image2.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', }, { uid: '-3', name: 'image3.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', }, { uid: '-4', name: 'image4.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', }, { uid: '-5', name: 'image.png', status: 'error', }, ]); const moveRow = useCallback( (dragIndex: number, hoverIndex: number) => { const dragRow = fileList[dragIndex]; setFileList( update(fileList, { $splice: [ [dragIndex, 1], [hoverIndex, 0, dragRow], ], }), ); }, [fileList], ); const onChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { setFileList(newFileList); }; return ( ( )} > ); }; export default App; ``` ```css #components-upload-demo-drag-sorting .ant-upload-draggable-list-item { border-top: 2px dashed rgba(0, 0, 0, 0); border-bottom: 2px dashed rgba(0, 0, 0, 0); } #components-upload-demo-drag-sorting .ant-upload-draggable-list-item.drop-over-downward { border-bottom-color: #1890ff; } #components-upload-demo-drag-sorting .ant-upload-draggable-list-item.drop-over-upward { border-top-color: #1890ff; } ```