react-dnd 須要react版本 > 16.6 ,貌似與react.memo方法有關 css
import React from 'react' // DragDropContext 相似React的Context // DragSource 高階組件 包裹被拖的元素 // DropTarget 高階組件 包裹被釋放的元素 import {DragDropContext, DragSource, DropTarget} from 'react-dnd'; // HTML5Backend 這個庫是必須的,相似於React的合成事件 // 解決瀏覽器差別,抽象事件操做爲能夠處理的state import HTML5Backend from 'react-dnd-html5-backend'; import "./index.css" const data = [ {id: 10, text: '1'}, {id: 11, text: '2'}, {id: 12, text: '3'}, {id: 13, text: '4'}, {id: 14, text: '5'} ] const datas = { data } class Item extends React.Component { constructor(props) { super(props) } render() { const {connectDragSource, connectDropTarget, move, ...restProps} = this.props; return ( connectDragSource( connectDropTarget( <div {...restProps}>{restProps.text}</div> ) ) ) } } const dragNode = DragSource('li', { beginDrag(props, monitor, component) { return { index: props.index, }; }, }, connect => ({ connectDragSource: connect.dragSource(), }))(Item); const DropNode = DropTarget('li', { drop(props, monitor) { const dragIndex = monitor.getItem().index; const hoverIndex = props.index; if (dragIndex === hoverIndex) return; props.move(dragIndex, hoverIndex); //monitor.getItem().index = hoverIndex; } }, function (connect) { return { connectDropTarget: connect.dropTarget() } } )(dragNode) class Demo extends React.Component { state = datas; moveRow = (start, end) => { let {data} = this.state; let temp = data[start] data[start] = data[end]; data[end] = temp; this.setState({data}) } render() { return ( <div className='move'> { this.state.data.map( (item, index) => { const prop = { move: this.moveRow, key: item.id, id: item.id, text: item.text, index: index } return <DropNode {...prop}/> }) } </div> ) } } export default DragDropContext(HTML5Backend)(Demo);