I have written an article about the use of React-dnd before, which may be a bit verbose, but the content is quite detailed, and many apis are listed. React-dnd: React-hooks + TypeSscript react-dnd: React-hooks + TypeSscript

preface

Current Version

  • react: 16.9.0
  • react-dom: 16.9.0
  • typescript: 3.5.3
  • react-dnd: 9.3.4
  • react-dnd-html5-backend: 9.3.4

NPM I create-react-app -g create-react-app -g create-react-app -g

Environment set up

  • Create scaffolding:npx create-react-app react-dnd-hooks --typescript
  • The installationreact-dnd:yarn add react-dnd
  • The installationreact-dnd-html5-backend:yarn add react-dnd-html5-backend

To facilitate uniform identification, ‘drag component ‘is replaced by ‘drag component’ and ‘target receive component’ is replaced by ‘drop component ‘


Wrap the root node with a DndProvider

To use React-dnd for drag and drop operations, you wrap the root node with the DndProvider label and pass in a backend parameter: the index.tsx file

import React from 'react';
import ReactDOM from 'react-dom';
import { DndProvider } from 'react-dnd';
import HTMLBackend from 'react-dnd-html5-backend'
import './index.css';
import App from './App';

ReactDOM.render(
    <DndProvider backend={ HTMLBackend }>
        <App />
    </DndProvider>,
    document.getElementById('root'));
Copy the code

Two, make the element can move

Let’s say we have a Box component that we want to drag and drop. Let’s declare it

Creating a Box component

Box.tsx

import React, { CSSProperties } from 'react'; const style: CSSProperties = { width: 200, height: 50, lineHeight: '50px', background: 'pink', margin: } const Box = () => {return (<div style={style}> Box</div>)} export default Box;Copy the code

At this point, we use the mouse to hold down the Box component, found that there is no way to drag the Box component

Let the Box component move

Using the useDrag provided by React-dnd, the first value returned is the object returned by the collect method (which is not used here, so it is omitted), and the second value returned is a ref, which is assigned to the element you want to drag to implement component dragging. Box.tsx

. import { useDrag } from 'react-dnd'; . Const Box = () => {// useDrag const [, drager] = useDrag({item: {type: 'Box'}}) return (ref={drager} style={style}> Box</div>)} export default Box;Copy the code

At this point we can drag the Box component back and forth with the mouse, but only drag, there is no place to receive the Box component, let’s see how to do it.


Create a Dustbin component to receive a drag component

Using the useDrop provided by React-Dnd, the first value returned is the object returned by the collect method. The second value returned is a ref, which is assigned to the drop component to be received by the drag component.

Refuse component:

import React, { CSSProperties } from 'react'; import { useDrop, DropTargetMonitor } from 'react-dnd'; const style: CSSProperties = { width: 400, height: 400, margin: '100px auto', lineHeight: '60px', border: } const Dustbin = () => {// the first argument is the object returned by the collect method, and the second argument is a ref value, Const [collectProps, droper] = useDrop({// accept is an object that must have the same type value as the item in the corresponding drag element, otherwise it cannot be accepted: Collect: (minoter: DropTargetMonitor) => ({isOver: minoter.isOver() }) }) const bg = collectProps.isOver ? 'deeppink' : 'white'; const content = collectProps.isOver ? Return (// assign droper to the corresponding element ref <div ref={droper} style={{... style, background: bg }}>{ content }</div> ) } export default Dustbin;Copy the code

Tips: Remember to reference the Box and Dustbin components to the app. TSX component for use.


Four, the effect diagram


Other common apis and matters needing attention

  • Drag components commonly used properties:

    • Item: is an object that must have a type attribute

    • Begin (mintor: DragSourceMonitor) : The component begins to drag and drop. An object must be returned that contains the type attribute. This will override the object returned by the item attribute and will be passed as the first argument to the hover and drop methods of the drop component

    • End (Item, mintor: DragSourceMonitor) : triggered when the component stops dragging. Item is the object returned by the drop component when the drop method is executed. It is equivalent to the value of mintor.getDropresult ()

  • Drop Common properties of the component

    • Accept: a string that must match the type value in the item attribute of the corresponding drag component

    • Hover (Item, Minoter: DropTargetMonitor) : Drag triggers when the drag component hove above the drop component

    • Drop (Item, Minoter: DropTargetMonitor) : Drag is triggered when dropped on the drop component at the end of drag. The returned value is passed as the first argument to the drag component’s end method

  • Allows components to both be dragged and receive drag elements

import React, { useRef } from 'react'; import { useDrag, useDrop } from 'react-dnd' const Card = () => { const ref = useRef<HTMLDivElement>(null); const [, drop] = useDrop({ accept: 'Card', }); const [, drag] = useDrag({ item: { type: 'Card' } }); Ref drag(drop(ref))); Return (<div ref={ref}> can be dragged and receive drag components </div>)}Copy the code
  • The DRAG component wants to pass some data out

    • Use the item attribute directly to pass:
      const [, drag] = useDrag({
          item: { type: 'Card', id: 1, name: 'card1', kind: 'Card }
      });
    Copy the code
    • Use the begin method to pass values:

    Note: The return value of the begin method overrides the item attribute, so be sure to pass the type attribute

      const [, drag] = useDrag({
          item: { type: 'Card' },
          begin(mintor: DragSourceMonitor) {
              return { type: 'Card', id: 1, name: 'card1', kind: 'Card }
          }
      });
    Copy the code
    • After thedropTargetThe receiving component can be retrieved in the first argument of the hover or drop methods, or usedDropTargetMonitorgetItem()Function.
  • I want to get some state information about the DRAG or drop component

    • dragComponents:
    Const [collectProps, drag] = useDrag({item: {type:}) const [collectProps, drag] = useDrag({item: {type:}) 'Card', id: 1, name: 'card1', kind: 'Card }, collect: (minoter: DropTargetMonitor) => ({ isOver: minoter.isOver(), }) });Copy the code
    • dropComponents:
    Const [collectProps, droper] = useDrop({collectProps, droper]) const [collectProps, droper] = useDrop({accept: 'Box', collect: (minoter: DropTargetMonitor) => ({ isOver: minoter.isOver(), }) })Copy the code
    • For more status information, see the DragSourceMonitor and DropTargetMonitor apis in my previous articles

A more complex Demo

A can be placed and drag and drop sort of example, interested partners can see.

rendering

The Demo address

react-dnd-hooks-demo

Welcome to Star! Welcome the Fork!


Seven, resource links

  • React-dnd official tutorial
  • React-Dnd