2022-11-1 react-dnd使用方法

115 阅读1分钟

index.js中引入DndProvider包裹使用区域并传入HTML5Backend

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <DndProvider backend={HTML5Backend}>
    <App />
  </DndProvider>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

DragBox.js (drag组件)

import React, { useState, useEffect } from 'react';
import './index.css';
import { useDrag } from 'react-dnd';

const DragBox = ({ item }) => {
  const [{ isDragging }, dragRef, dragPriview] = useDrag(() => ({
    type: 'box',  //需和对应丢入的drop的accept属性相同才能放入
    item,  //对应的item属性
    collect: (monitor) => ({   //监视器
      isDragging: monitor.isDragging()
    })
  }))
  if(isDragging) {
    return <div ref={dragRef}></div>
  }
  return (
    <div className="drag-item" ref={dragRef}>{item.id}</div>  
    //需要拖动的元素加上ref={dragRef}
  )
}

export default DragBox

drop组件

import React from 'react';
import './index.css';
import { useDrop } from 'react-dnd';
const DropBox = ({ item }) => {
  const [{canDrop, isOver}, dropRef] = useDrop(() => ({
    accept: 'box',  //需要与Drag组件的type相同才能放入
    collect: (monitor) => ({  //监视器
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop()
    }),
    drop: (item) => {  
      console.log(item);  //打印对应放入的Drag组件的item
    }
  }))

  return (
    <div className="drop-item" ref={dropRef}>{item.id}</div>
  )
}

export default DropBox

App.js

import React, { useState, useEffect } from 'react';
import DragBox from './components/DragBox';
import DropBox from './components/DropBox';
import './App.css';
import { useDrop } from 'react-dnd';

const App = () => {
  const [dragList, setDragList] = useState([
    {
      id: 0
    },
    {
      id: 1
    },
    {
      id: 2
    }
  ]);
  const [dropList, setDropList] = useState([
    {
      id: 4
    },
    {
      id: 5
    }
  ]);
  const [{canDrop, isOver}, dropRef] = useDrop(() => ({
    accept: 'box',
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop()
    }),
    drop: (item) => {  //丢入的对应Drag的item属性,判断是哪个Drag丢入Drop区域
      console.log(item);
      let list = [...dragList];
      let index = list.findIndex((it)=> item.id === it.id);
      list.splice(index, 1);
      setDragList(list);
      
      setDropList([...dropList, item]);
    }
  }), [dragList, dropList])  
  //由于该hook底层包裹了useMemo,所以需要把更改的state加入依赖

  return (
    <div>
      <div className="drag-box-area">
        {
          dragList.map((item) => (
            <DragBox key={item.id} item={item} state={dragList}/>
          ))
        }
      </div>
      <div className="drop-box-area" ref={dropRef}>
        {
          dropList.map((item) => (
            <DropBox key={item.id} item={item} state={dropList}/>
          ))
        }
      </div>
    </div>
  )
}

export default App;