首页 > 其他分享 >React-DnD的简要使用方法与API文档

React-DnD的简要使用方法与API文档

时间:2023-04-14 14:34:40浏览次数:47  
标签:返回 DnD monitor DOM React item API 拖拽 拖放

前提

它这个官方文档贼难进去,而且第一次看的时候也不太好理解,这篇文章就把一些常用的内容记下,希望能帮助到大家。本篇文章参考的是16.0.1版本

npm i react-dnd

1 简单示例

先不说具体API,来看下常用示例~

1.1 useDrag:让DOM允许拖拽

import React from 'react'
import { useDrag } from 'react-dnd'

export default function Player() {
  // 第一个返回值是一个对象,主要放一些拖拽物的状态。后面会介绍,先不管
  // 第二个返回值:顾名思义就是一个Ref,只要将它注入到DOM中,该DOM就会变成一个可拖拽的DOM
  const [_, dragRef] = useDrag({
      type: 'Player', // 给拖拽物命名,后面用于分辨该拖拽物是谁,支持string和symbol
      item: { id:1  }, // 拖拽物所携带的数据,让后面一些事件可以拿到数据,已达到交互的目的
    },[])

  // 由上面示例可知, useDrag所接收的参数一个是对象/函数 和一个依赖数组(可选)

  // 注入Ref,现在这个DOM就可以拖拽了
  return (
    <div ref={dragRef}></div>
  )
}

1.2 useDrop:让DOM作为拖放区域

import { useDrop } from 'react-dnd'

export const Dustbin = () => {
  const [_, dropRef] = useDrop({
    accept: ['Player'],  // 指明该区域允许接收的拖放物。可以是单个,也可以是数组
    // 里面的值就是useDrag所定义的type
    
    // 当拖拽物在这个拖放区域放下时触发,这个item就是拖拽物的item(拖拽物携带的数据)
    drop: (item) => {},
  })

  // 将ref注入进去,这个DOM就可以处理拖拽物了
  return (
    <div ref={dropRef} ></div>
  )
}

1.3. 组合:让DOM作为拖拽物和拖放区域

import React, { useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';

const Player=({onChangePosition,id})=>{
	const ref = useRef(null);

	// 1. 让DOM作为拖拽物,允许拖放
	const [_, drag] = useDrag(() => ({
	  type: 'PLAYER', 
	  item: { id:1 }  
	}));

	// 2. 让DOM作为可拖放的区域
	const [, drop] = useDrop(() => ({
	  accept: ['PLAYER'],  
	  drop(item) {
		 if (onChangePosition) {
			onChangePosition(item.id,id);
		 }
	  }
	}));

	// 3. 让目标DOM即能作为拖拽物,也能作为拖放区域
	drag(drop(ref));

	// 4. 下面就是施展魔法,把ref注入DOM中
	return <div ref={ref}></div>
}

下面就是枯燥的API搬运了,为了方便理解,以下内容中,由useDrag注册的DOM将称为拖拽物,有useDrop注册的DOM将称为拖放区域

2. useDrag

先放一个官网比较完整的示例:

import { useDrag } from 'react-dnd'

function DraggableComponent(props) {
  // 返回三个值:
  // collected:是一个对象,下面的collect函数返回什么,就有什么,常用于判断拖拽物的状态
  // drag:拖拽物Ref
  // dragPreview: 当DOM处于拖拽状态时,所显示的DOM的ref
   const [{ isDragging }, drag, preview] = useDrag({
      type: 'BOX',
      item: { id:1  },
      // 这个monitor会提供拖拽物状态的信息,我会在下面罗列所有monitor支持的方法
      collect: (monitor) => ({
        isDragging: monitor.isDragging(),  // 是否处于拖拽状态
      }),
    },[],
  )

  return collected.isDragging ? (
    <div ref={preview} />
  ) : (
    <div ref={drag} style={{color:isDragging?'red':'green'}}>
      ...
    </div>
  )
}

2.1 返回值与参数对象

const [collected,dragRef,dragPreviewRef]=useDrag({
	type:'Player',
	item:{id:1},
	previewOptions:{},
	end(item, monitor){...}, // 拖拽停止时调用,item是拖拽物在上方定义的数据
	canDrag(monitor){...},
	isDragging(monitor){...},
	collect(monitor ,props)=>({...})
},[])

  • 返回值
名称 描述
Collected Props speccollect函数返回的属性
DragSource Ref 拖拽物的引用
DragPreview Ref 处于拖拽状态的拖拽物的引用
  • 参数
名称 描述
spec 一个对象或者创建一个返回对象的函数。该对象是一个特定对象
deps 依赖数组

其中spec的对象属性如下:

属性 描述
type 必填。string或symbol类型。拖放区域所接受的拖拽物将从这里挑选
item 必填。函数或对象。拖拽物携带的数据。如果传对象,不建议使用多层嵌套或复杂的对象
previewOptions 用于描述 dragPreviewRef的对象
end(item, monitor) 拖拽停止时调用。可在函数内调用monitor.didDrop() 来判断该拖拽物是否被放在所定义的拖放区域中。如果拖放区域定义了drop(),那么可以通过monitor.getDropResult() 去获取drop返回的类型
canDrag(monitor) 返回布尔值。指明该拖拽物是否允许拖拽。如果想一直允许拖拽,则可以忽略这个属性。(无法再内部调用monitor.canDrag()
isDragging(monitor) 返回布尔值。指明拖拽物是否处于拖拽状态。默认情况下,当拖拽物正拖拽时则被认为是处于拖拽状态。(无法再内部调用monitor.isDragging()
collect(monitor ,props) 返回对象的函数。可以从useDrag返回的第一个值获取

2.2 monitor 属性

记录了拖拽物状态信息,支持的属性如下:

属性 描述
canDrag() 如果没有拖拽操作正在进行,返回true;
isDragging() 如果有拖拽操作正在进行,返回true;
getItemType() 返回拖拽物的定义的type
getItem() 返回拖拽物的定义的item
getDropResult() 当拖放结束,返回拖放区域定义的drop()所返回的对象
didDrop() 如果拖放区域执行了drop(),返回true,即便drop()没有返回对象,也返回true
getInitialClientOffset() 返回拖拽开始时,拖拽物的起点位置
getInitialSourceClientOffset() 返回拖拽开始时,拖拽物的根节点的位置
getClientOffset() 当拖拽正在进行时,返回拖拽物再次过程中最后的位置
getDifferenceFromInitialOffset() 返回最后记录的位置与起点位置的差值
getSourceClientOffset() 返回拖拽物当前在根组件位置与拖拽物最初在根组件位置的差值

3. useDrop

const [collected,dropRef]=useDrop({
	accept:'Player',
	drop(item, monitor){...}, // 拖拽物拖拽进来是调用,item为拖拽物携带的数据
	hover(item, monitor){...}  // 拖拽物悬浮在拖放区域时,item为拖拽物携带的数据
	canDrop(item, monitor){...}
	collect(monitor ,props)=>({...})
},[])

3.1 参数对象

属性 描述
accept 必填。指定拖放区域所接受的拖拽物。string或symbol类型,或者是数组。
drop(item, monitor) 当拖拽物被拖拽进来是调用。而如果函数返回对象,那么对应拖拽物end方法则可以通过monitor.getDropResult() 来获取这个对象
hover(item, monitor) 当拖拽物悬浮在拖放区域时调用。 可以通过monitor.isOver({ shallow: true })来指定是否只悬浮在单个拖放区域上,而不悬浮在嵌套的拖放区域上
canDrop(item, monitor) 返回布尔值。指明该拖放区域是否可用。如果是一直可用,忽略即可。
collect(monitor ,props) 返回对象的函数。可以从useDrop返回的第一个值获取

3.2 monitor 属性

记录了拖放区域拖拽物状态信息,支持的属性如下:

属性 描述
canDrop() 如果有拖拽操作正在进行,返回true;
isOver(options) 如果有拖拽操作正在进行并悬浮在拖放区域上,返回true;可传入{ shallow: true }来指定是否只悬浮在该区域上,而不是悬浮在嵌套的拖放区域上
getItemType() 返回当前拖进来的拖拽物定义的type
getItem() 返回当前拖进来的拖拽物定义的item
getDropResult() 返回当前拖放区域定义的drop()返回的对象
didDrop() 如果拖放区域执行drop()操作,返回true

标签:返回,DnD,monitor,DOM,React,item,API,拖拽,拖放
From: https://www.cnblogs.com/sanhuamao/p/17318203.html

相关文章

  • FFmpeg API 熟悉记录,目标:播放本地MP4
    简要熟悉api之后包括解码器,编码器,输入输出文件之后,开始分析ffplay,我们知道ffplay使用的是sdl的相关库进行播放,在这里我将把sdl舍弃,移植到android平台上即可。简单手撸播放器的想法,看了几天代码和ffplay的源码分析,和ijkplayer的部分实现思路,总结来说,大致流程图比较简单,先熟......
  • API管理
    API管理包括创建和发布API、制定使用策略、控制访问权限、培养用户社区、搜集与分析使用统计数据以及报告性能等过程,通常包含API网关、开发者门户等组件。其中,API网关作为关键组件,负责处理和转发请求,同时执行安全和性能策略,而开发者门户则是一个在线平台,为开发者提供API文......
  • 品类超全的热门免费可用 API 汇总
     书籍AnAPIOfIceAndFire-冰与火之歌的API提供JSON格式的“冰与火之歌”宇宙中的所有书籍,人物,房屋的数据.无需验证身份.Node和Swift库可用.OpenLibraryBooksAPI-OpenLibrary是一个开放的,可编辑的图书馆目录,为每一本出版的图书都建立了网页. ......
  • homebrew 无法从 API 更新错误问题
    今天中午吃饭前,想看看有没有更新,于是打开终端模拟器(我用的是WezTerm),brewupdate,结果更新出了点问题大致情况就是我不能从API更新,这个特性是从homebrew进入4.0大版本才出现的,我也遵循了默认设置。然而在今天,它出错了。我以为是路由配的节点挂了,然后随手ping了一下上面......
  • popState api详解 history.pushState 案例
    popStateAPI是HTML5引入的一种浏览器历史记录相关的API。它提供了一种监听浏览器历史栈发生变化的途径,当用户通过前进/后退按钮或者其他方式改变了当前的历史状态时,该API就会触发相应的事件,开发者可以在事件处理函数中通过获取到的历史状态数据做出相应的响应。在使用popStateA......
  • rv1126 获取图像数据,实现图像裁剪、缩放、旋转【RK_MPI API接口】
    前言刚接触RK平台,目前正在学习探索阶段,欢迎朋友们一起讨论,指出文章错误和可以优化的地方;如果想参照文中描述进行编译、执行程序,请先参考阅读rv1126SDK编译和rv1126数据流;版本说明,测试使用SDK版本是2020-0912版本,文中记录的问题,可能在新版本已经解决;文中使用的接口函数,可能老版本......
  • android: minSdkVersion、targetSdkVersion、CompileSdkVersion三个api版本号的区别
    一,minSdkVersion:   app可以安装的最低的api版本:   1,安装:googleplay和应用市场会根据用户的api版本,           判断用户是否可以看到你的app    2, 运行:在minSdkVersion指定版本的api上运行时,           ......
  • 【Azure Developer】使用 Microsoft Graph API 获取 AAD User 操作示例
    问题描述查看官方文档“ Getauser ”,产生了一个操作示例的想法,在中国区Azure环境中,演示如何获取AADUser信息。 问题解答使用MicrosoftGraphAPI,演示如何获取AADUser信息,因参考文档是针对GlobalAzure,所以文档种的URL为://GlobalAzureMicrosoftGraphAPIHostG......
  • 盘点 8 款好用的 API 接口文档管理工具
    随着互联网的普及和发展,API 接口已经无处不在。它已经在Web应用程序、移动应用程序、云计算、物联网、人工智能等领域中得到广泛应用。例如,在金融行业中,API接口可以被用于构建支付服务、银行服务和证券交易服务等;在医疗行业中,API接口可以被用于构建病历管理系统、健康监测系统......
  • React 使用NPM创建项目
    React使用NPM创建项目虽然研究React已经有一段时间,但之前写Demo都是直接新建文件夹然后在里面写html和js,究其原因还是因为之前用不了NPM。现在终于是把NPM的问题解决了(从IDEA上copy了个代理的地址),这下才能算是真正的DEV环境。但有了NPM反而不知道怎么创建项......