react-dnd 最简单易懂的列表排序

import React, { Component } from 'react'
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'

// 被拖拽的项
const source = {
  // 卡片开始被拖拽时触发
  beginDrag(props) {
    // console.log('开始被拖拽', props.index)
    return {
      index: props.index
    }
  },
  // 卡片结束拖拽时触发
  endDrag(props) {
    // console.log('结束拖拽', props.index)
  }
}

// 拖拽目的项
const target = {
  props(props, monitor) {
    const dragIndex = monitor.getItem().index         // 被拖拽前的位置
    const hoverIndex = props.index                    // 拖拽后的位置
    // 拖拽位置不变
    if (dragIndex === hoverIndex) {
      return;
    }
	props.handleMove(dragIndex, hoverIndex)
  }
}

const DraggbleDiv = props => {
  const { connectDragSource, connectDropTarget, item, index } = props
  return (
    connectDragSource(connectDropTarget(
      <div key={index}>{item.title}</div>
    ))
  )
}

const DraggbleBox = (
  DragSource('test', source, (connect, monitor) => ({
    connectDragSource: connect.dragSource()
  })))(DropTarget('test', target, (connect, monitor) => ({
    connectDropTarget: connect.dropTarget()
  }))(DraggbleDiv)
)

class demo extends Component {

	constructor(){
	    super()
	    this.state = {
	      list: [{
	        title: '更新内容'
	      },{
	        title: '更新时间'
	      },{
	        title: '学习提醒'
	      }]
	    }
	
	    this.handleMove = this.handleMove.bind(this)
	
	  }
	
	handleMove(dragIndex, hoverIndex){
	    const { list } = this.state
	    const temp = list[dragIndex]
	    if(dragIndex > hoverIndex){
	      for(let i = dragIndex; i > hoverIndex; i--){
	        list[i] = list[i-1]
	      }
	    }else{
	      for(let i = dragIndex; i < hoverIndex; i++){
	        list[i] = list[i+1]
	      }
	    }
	    list[hoverIndex] = temp
	    this.setState({ list })
	  }
	
	render() {
	
	    const { list } = this.state
	
	    return (

		 <div>
		     <DndProvider backend={HTML5Backend}>
		       {
		         list.map((item, index) => (
		           <DraggbleBox 
		             item={item}
		             index={index}
		             key={index}
		             handleMove={this.handleMove}
		           />
		         ))
		       }
		     </DndProvider>
		   </div>
	
	    )
	  }
	
}

export default demo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
React-dnd 拖拽排序是一种常见的前端交互方式,可以通过以下代码实现:1. 首先需要安装 react-dndreact-dnd-html5-backend 两个库:``` npm install --save react-dnd react-dnd-html5-backend ```2. 在组件中引入 DragDropContext、Droppable 和 Draggable 组件:``` import { DragDropContext, Droppable, Draggable } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; ```3. 定义一个数组作为拖拽列表的数据源:``` const items = [ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' }, { id: 4, name: 'Item 4' }, { id: 5, name: 'Item 5' }, ]; ```4. 在组件中使用 DragDropContext 组件包裹整个列表,并在其中使用 Droppable 组件包裹每个拖拽项:``` <DragDropContext backend={HTML5Backend}> <Droppable droppableId="items"> {(provided) => ( <ul {...provided.droppableProps} ref={provided.innerRef}> {items.map((item, index) => ( <Draggable key={item.id} draggableId={item.id.toString()} index={index}> {(provided) => ( <li {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef} > {item.name} </li> )} </Draggable> ))} {provided.placeholder} </ul> )} </Droppable> </DragDropContext> ```5. 在 Draggable 组件中使用 provided.draggableProps 和 provided.dragHandleProps 属性来实现拖拽功能,同时使用 provided.innerRef 属性来获取拖拽元素的引用。6. 在 Droppable 组件中使用 provided.droppableProps 和 provided.innerRef 属性来实现拖拽排序功能。7. 最后,需要在 DragDropContext 组件中定义 onDragEnd 回调函数来处理拖拽结束后的逻辑:``` function onDragEnd(result) { if (!result.destination) { return; } const newItems = Array.from(items); const [reorderedItem] = newItems.splice(result.source.index, 1); newItems.splice(result.destination.index, , reorderedItem); setItems(newItems); }<DragDropContext backend={HTML5Backend} onDragEnd={onDragEnd}> ... </DragDropContext> ```8. 在 onDragEnd 回调函数中,首先判断是否有目标位置,如果没有则直接返回。然后使用 Array.from 方法复制一份原始数据源,从中取出被拖拽的元素并删除,再将其插入到目标位置中,最后使用 setItems 函数更新数据源。以上就是 react-dnd 拖拽排序的代码实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值