Today, when I was doing my own project, I felt comfortable to use drag-and-drop sorting for the modification of the order of page rotation. So I did a bit of react-DND, and I made a note of it.

React-dnd Document Address: Official document

Firstly.

There are two dependencies to install.

cnpm i react-dnd react-dnd-html5-backend -S
Copy the code

In order to implement drag sorting, first need to make the box can be dragged, dragged at the same time also can accept other people’s drag, preview:

2. Related APIS

DndProvider (all drag operations should be in here)

1. The attribute

Backend is mandatory. You can use the HTML5 backend that comes with React-Dnd, except for custom react-Dnd backend code.Copy the code

UseDrag (a hook to enable dragging)

1. Parameters (read the documentation for details)

Is a js object that must define item and its value must be a string!Copy the code

2. The return value

Subscript 0: the object that contains the collect attribute from collect, that is, the optional member of the argument object collect, which returns {} 2 if not written. (subscript 1: drag source connector function types for the function, the parameter type must be the React. RefObject < any > | React. ReactElement Element | | null), throw the ref is finished. 3. Subscript 2: Connector function for dragging preview. This can be appended to the DOM preview section. I don't need it hereCopy the code

UseDrop (a hook to enable dragging)

1. Parameters (read the documentation for details)

Accept is a js object that must define accept as a string!Copy the code

2. The return value

Subscript 0: the object that contains the collect attribute from collect, that is, the optional member of the argument object collect, which returns {} 2 if not written. Subscript 1: place the connector function of the target (type is function, parameter type is the same as described in useDrag), drop ref in and you are done.Copy the code

Three.

(Out of the three pieces can play the group)

Create a new component that acts as the drag source and the component that receives the drag.

DragDropBox.jsx

import React, { useRef } from 'react' import { useDrop, useDrag } from 'react-dnd' export default ({ id, text, index, ChangePosition, className}) => {const ref = useRef(null) Const [, drop] = useDrop({accept: 'DragDropBox', hover: const [, drop] = useDrop({accept: 'DragDropBox', hover: (item, monitor) => {// If (! Ref. Current) return let dragIndex = item.index let hoverIndex = index if (dragIndex === hoverIndex) return ChangePosition (dragIndex, hoverIndex) // Call the method passed in to complete the exchange of item.index = hoverIndex // Assign the current index moved to Box to the current dragged Box, Otherwise there will be two boxes crazy shake! } }) const [{ isDragging }, drag] = useDrag({ item: { type: 'DragDropBox', id, index, text }, collect: monitor => ({ isDragging: Monitor. IsDragging () // CSS style required})}) return (// ref this process allows this component to be dragged as well as dragged <div ref={drag(drop(ref))} style={{ opacity: isDragging ? ClassName ={classname. dragBox}> <h2>{' 第 ${index + 1} screen '}</h2> <h2 style={{fontSize: '30px' }}>{ id + '.' + text }</h2> </div> ) }Copy the code

Create a new component and reference it.

Swipe.jsx

import React, { useState, useEffect } from 'react' import style from './swipe.module.scss' import { DndProvider } from 'react-dnd' import { HTML5Backend } from 'react-dnd-html5-backend' import DragDropBox from './DragDropBox' import { cloneDeep } from 'lodash' Import Card from '@/component/ Card/Card '// elam UI el-card, Import {MinusOutlined} from '@ant-design/ ICONS 'import {Button, Popconfirm, message } from 'antd' const initData = [ { id: 1, text: '111' }, { id: 2, text: '222' }, { id: 3, text: '333' }, { id: 4, text: '444' }, { id: 5, text: '555' }, { id: 6, text: '666' } ] const Swipe = () => { const [isChangePosition, setIsChangePosition] = useState(false) const [boxList, setBoxList] = useState(initData) useEffect(() => { sessionStorage.initData = JSON.stringify(initData) return () => { sessionStorage.removeItem('initData') } }, []) const changePosition = (dragIndex, HoverIndex) => {let data = cloneDeep(boxList) let temp = data[dragIndex] // dragIndex = data[hoverIndex] Data [hoverIndex] = temp setBoxList(data)} // Change order button const changePositionBtn = () => {message.info(' Please drop pictures to sort! ') setIsChangePosition(true)} // cancelChangePosition const cancelChangePosition = () => {setIsChangePosition(false) Parse (sessionStorage.getitem ('initData')))} const saveChangePosition = () => { SetIsChangePosition (false) sessionStorage.initData = json.stringify (boxList) // Send a request here to update backend data message.success(' Updated order! ') } const deleteImgOne = id => { console.log(id) } return( <div style={{ height: '100%' }}> <Card bottom> { isChangePosition ? <> <Button onClick={ cancelChangePosition } style={{ marginRight: </Button type="primary" onClick={saveChangePosition}> Save </Button> </> : <Button type="primary" onClick={changePositionBtn} </Button> </Card> <Card> {isChangePosition? <DndProvider backend={ HTML5Backend }> <div className={ style.dragBoxContainer }> { boxList.map((value, i)=> <DragDropBox className={ style } key={ value.id } index={ i } id={ value.id } text={ value.text } changePosition={ changePosition } /> ) } </div> </DndProvider> : <div className={ style.dragBoxContainer }> { boxList.map(value=> ( <div key={ value.id } className={ [ style.dragBox, Style.deleteicon].join(' ')} > <Popconfirm title=" Do you want to delete this image? Placement ="top" onConfirm={() => deleteImgOne(value.id)} okText=" ok "cancelText=" cancel" > <div className={ style.deleteIconBox }> <MinusOutlined className={ style.deleteIcon }/> </div> </Popconfirm> { value.id } - { value.text } </div> )) } <div className={ [style.dragBox, style.addImgBox].join(' ') }/> </div> } </Card> </div> ) } export default SwipeCopy the code

Swipe. JSX style file

swipe.module.scss

.card{
 height: 200px;
 width: 200px;
 background-color: pink;
 margin: 0 15px 15px 0;
}

.dragBoxContainer{
 width: 100%;
 height: 100%;
 display: grid;
 grid-template-columns: repeat(auto-fill, 360px);
 grid-template-rows: repeat(auto-fill, 180px);
 grid-gap: 15px;
 justify-content: center;
 align-items: center;
}

.dragBox{
 position: relative;
 display: flex;
 flex-direction: column;
 height: 180px;
 width: 100%;
 background-color: pink;
 padding: 10px;
 overflow: hidden;
 border-radius: 12px;
 h2{
   font-size: 20px;
 }
 .imgBox{
   flex-grow: 1;
   width: 100%;
   background-color: #fff;
 }
 .deleteIconBox{
   content: '';
   display: block;
   width: 0;
   height: 0;
   border-left: 40px solid transparent;
   border-top: 40px solid red;
   position: absolute;
   right: 0;
   top: 0;
   cursor: pointer;
 }
 .deleteIcon{
   color: #fff;
   font-size: 16px;
   position: absolute;
   bottom: 18px;
   right: 4px;
 }
}

.addImgBox{
 border: 1px dashed #ccc;
 background-color: transparent;
}
Copy the code