译文: 告别 React-DnD,拥抱 Dnd Kit:拖放的未来已经来了!

以前,在React中实现拖放功能首选 React-DnD 库。由于该库具有强大的功能并且对于 React 开发人员来说易于使用,因此它被广泛推荐。

然而,现在出现了一个新的竞争者,提供了一个更强大、更好、更易于学习的解决方案:Dnd Kit。

虽然必须承认 React-DnD 仍然是一个不错的库,但 Dnd Kit 提供了许多优点,使其成为一个具有吸引力的替代方案。

例如,在功能方面,Dnd Kit 相对于 React-DnD 提供了许多改进。它更强大、更高效,并提供更好的用户体验。然而,选择哪个库最适合个人开发者的需求,取决于个人开发者自己的决定。

如果你问我,我更喜欢 Dnd Kit,也最常用它,这就是我写这篇文章让你也熟悉它的原因。

请记住,我遵循了官方文档,因此代码看起来是相同的。但我已尽力以尽可能简单的方式解释了这个概念。

此外,未来还将有一系列的文章,我将在其中解释一些复杂的示例,所以请关注我以获取更新,以便在我发布下一篇文章时得到通知。

现在让我们继续进行。

为什么选择 Dnd Kit ?

根据官方网站介绍,Dnd Kit 是一个轻量级、模块化、高性能、易于访问和可扩展的 React 拖放工具包。

它可以让你轻松拖放组件。

说到您可以创建的内容,实际上有大量的示例。其中一些最好的示例如下:

1. 看板

2. 跳棋游戏

3. 纸牌游戏

很酷吧?

同样,您也可以根据自己的喜好实现任何拖放功能。

因此,让我们深入研究并使用 Dnd Kit。

在 React 应用程序中使用 Dnd Kit

首先,我们必须安装 Dnd Kit。

在 React 项目中安装 Dnd Kit 非常简单。

1. 安装

首先,您必须使用标准命令创建一个 React 应用程序。

lua 复制代码
npx create-react-app appname

译者注: 这里推荐使用更轻便、更快捷的vite,初始化命令: npm create vite

然后就可以安装 Dnd Kit 软件包了。为此,您只需安装核心库,它包含了您所需的大部分主要功能。

请在 React 应用程序中运行以下命令。

bash 复制代码
npm install @dnd-kit/core

还有一些 Dnd 工具包,即修改器和可排序包,我们将在以后的文章中使用。

2. 了解 Dnd Kit 的工作原理

首先,请允许我解释一下 Dnd Kit 库背后的一些基本概念。

在使用 Dnd Kit 之前,您应该熟悉 React 中的 ref。如果您不知道,这里有相关文档。

现在让我们继续进行。

要使用 Dnd Kit 库,您需要定义两个组件:一个 Draggable 组件和一个 Droppable 组件。

Draggable 组件是可以拖动的元素,而 Droppable 组件则是可以放置 Draggable 组件的地方。

最后,为确保 Draggable 和 Droppable 组件之间的交互,这两个组件都必须置于 DndContext 组件内,后者充当父组件。

这样,DndContext 组件就可以管理两个组件之间的交互,并提供一个集中的地方来处理拖放功能。

以下是我上面解释内容的示例代码:

jsx 复制代码
import React from 'react';
import {DndContext} from '@dnd-kit/core';

import {Draggable} from './Draggable';
import {Droppable} from './Droppable';

function App() {
  return (
    <DndContext>
      <Draggable />
      <Droppable />
    </DndContext>
  )
}

如果上面的代码让你感到困惑,不用担心;我们稍后会仔细讲解它。只需要记住,我们有一个 DndContext 父组件和两个附加组件(Draggable、 Droppable)在其中。

3. 一个拖放示例

现在,您已经了解了 Dnd Kit 的一些基本概念,让我们举一个简单的例子。

在此之前,先让我向大家展示一下我们正在创造的东西。

在这里,左边一列由一个 Draggable 组件组成,右边一列由一个 Droppable 组件组成。

因此,让我们创建这两个组件。

创建 Draggable 组件

在 React 应用程序的 src 文件夹中新建一个名为 Draggable.jsx 的文件,然后粘贴下面的代码。

jsx 复制代码
import React from 'react';
import { useDraggable } from '@dnd-kit/core';

export function Draggable(props) {
    const { attributes, listeners, setNodeRef, transform } = useDraggable({
        id: 'draggable',
    });
    const style = transform ? {
        transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
    } : undefined;

    return (
        <button ref={setNodeRef} style={style} {...listeners} {...attributes}>
            {props.children}
        </button>
    );
}

在这里,我们定义了一个名为 Draggable 的 React 组件,它使用 Dnd Kit 库实现了可拖动元素的功能。代码从 @dnd-kit/core 库中导入了 useDraggable 钩子,用于为组件提供拖放功能。

然后,我们使用了 "useDraggable "钩子,该钩子会返回一个对象,其中包含几个用于实现可拖动功能的属性。

该对象包含以下属性:

  • attributes: 一个对象,包含使组件可拖动所需的 HTML 属性
  • listeners: 包含用户拖动组件时触发的事件监听器的对象
  • setNodeRef: 用于设置组件 DOM 节点引用的函数
  • transform: 一个对象,包含组件当前的 x 和 y 移位(以像素为单位)

"Draggable" 组件使用 "transform" 属性对组件应用平移。这是通过创建一个包含平移的 "style" 对象,并使用 "style" 属性将其应用于组件来完成的。

最后,我们定义了一个按钮元素,通过 "useDraggable "钩子中的 "setNodeRef "函数设置 DOM 节点的ref引用。该钩子的 "listeners" 和 "attributes" 对象分别使用 "...listeners" 和 "...attributes" 展开语法,将属性展开到组件上。

创建 Droppable 组件

现在,在 React 应用程序的 src 文件夹中新建一个名为 Droppable.jsx 的文件,并粘贴下面的代码。

jsx 复制代码
import React from 'react';
import { useDroppable } from '@dnd-kit/core';

export function Droppable(props) {
    const { isOver, setNodeRef } = useDroppable({
        id: 'droppable',
    });
    const style = {
        color: isOver ? 'blue' : undefined,
    };


    return (
        <div ref={setNodeRef} style={style}>
            {props.children}
        </div>
    );
}

在这里,useDroppable 钩子会返回一个包含两个属性的对象:

  • isOver: 布尔值,表示可拖动组件当前是否位于可下垂组件的上方
  • setNodeRef: 用于设置组件 DOM 节点引用的函数

那么代码就很简单了,如果可拖动组件位于可下垂组件的上方,那么 isOver 将为 true,因此蓝色将被应用。

创建父组件

请记住,我们必须创建一个包含这两个组件的父组件。

现在,让我们来创建它。

jsx 复制代码
import React, { useState } from 'react';
import { DndContext } from '@dnd-kit/core';
import './App.css'
import { Droppable } from './Droppable';
import { Draggable } from './Draggable';

function App() {
  const [isDropped, setIsDropped] = useState(false);
  const draggableMarkup = (

    <Draggable >
      <div className='drag_item'>
        Drag me
      </div>
    </Draggable>
  );

  return (
    <DndContext onDragEnd={handleDragEnd}>
      <div className='section'>
        <div className='draggable'>
          {!isDropped ? draggableMarkup : null}
        </div>
        <div className='draggable'>
          <Droppable>
            {isDropped ? draggableMarkup : 'Drop here'}
          </Droppable>
        </div>
      </div>
    </DndContext>
  );

  function handleDragEnd(event) {
    if (event.over && event.over.id === 'droppable') {
      setIsDropped(true);
    }
  }
}

export default App;

在 App 组件中,我们定义了一个状态变量 isDropped,用于跟踪可拖动项目是否已被拖放到可下放区域。

简单来说,我们有一些条件,要么显示可拖动的项目,要么显示一个消息,指示可以放置项目的位置。

在主渲染函数中,代码返回一个 DndContext 组件,并将回调函数 handleDragEnd 作为 prop 传递。当拖放操作完成时,将调用该回调函数。然后,我们有两个带有类名 "draggable" 的 div,用于应用相同的样式。

第一个 div 的子组件是 draggableMarkup 组件,但仅当 isDropped 为 false 时才显示。第二个 div 的子组件是 Droppable 组件。如果 isDropped 为 true,则显示 draggableMarkup 组件,否则显示文本 "Drop here"。

最后,handleDragEnd 函数检查 event.over 属性是否存在,以及 event.over 对象的 id 是否为 "droppable"。如果是,则通过调用 setIsDropped(true) 更新状态。

为你的React应用添加样式

最后,我们需要为我们的 React 应用程序应用样式。为此,您可以使用任何 CSS 框架,但我将简单地在 src 文件夹内创建一个新的 App.css 文件,并将以下代码添加到其中。

css 复制代码
.section {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: rgb(37, 148, 251);
}

.draggable {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20rem;
  height: 20rem;
  background-color: #9749FF;
  margin-right: 10px;
  color: white;
}

.drag_item {
  padding: 5px 10px;
  width: 8rem;
  height: auto;
  color: black;
  background-color: white;
}

就是这样,现在你可以运行应用程序并查看输出结果了。

希望你喜欢。

就这样--谢谢。

此外,未来还会有一系列关于 Dnd Kit 的文章,请务必关注我

原文链接

如侵则删

相关推荐
wakangda1 小时前
React Native 集成原生Android功能
javascript·react native·react.js
北京_宏哥3 小时前
python接口自动化(四十)- logger 日志 - 下(超详解)
python·前端框架·自动化运维
CoderLiu3 小时前
用Rust写了一个css插件,sass从此再见了
前端·javascript·前端框架
秃头女孩y7 小时前
【React中最优雅的异步请求】
javascript·vue.js·react.js
前端小小王13 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发14 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
不是鱼18 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js
川石教育19 小时前
Vue前端开发-缓存优化
前端·javascript·vue.js·缓存·前端框架·vue·数据缓存
飞翔的渴望21 小时前
antd3升级antd5总结
前端·react.js·ant design
╰つ゛木槿1 天前
深入了解 React:从入门到高级应用
前端·react.js·前端框架