一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu

react-beautiful-dnd使用心得及踩坑记录

最近项目中用到了一个新依赖 react-beautiful-dnd,在这里记录一下使用的过程及遇到的一些坑。

引入

此依赖用于React框架。
使用 npm i react-beautiful-dnd --save 安装。
安装完毕后,在需要使用拖拽元素功能的页面引入组件。
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"

结构

react-beautiful-dnd 官方对于使用拖拽组件的结构用了一张图片标识,这张图很清晰地展示了拖拽元素所处的结构关系。
react-beautiful-dnd使用心得及踩坑记录
<DragDropContext> :最外层包裹拖拽区域的wrap。
<Droppable> :某个包含若干个可拖拽项的组。
<Draggable> :可拖拽项。

我使用的是最简单的若干个项拖拽,
以下是我的原代码结构

<div className="myModal">
  <div className="modalList">
    {this.state.modalListInModal.map((item) => (
      <div className="modal" key={item.name}>
        <img src={item.imgUrl} alt="" />
        <span title={item.wording}>{item.wording}</span>
      </div>
    ))}
  </div>
</div>

按照上面的gif图结构,我写出了如下结构

<DragDropContext onDragEnd={this.onDragEnd}>
  <div className="myModal">
    <Droppable droppableId="mymodal" direction="horizontal">
      {(provided) => (
        <div
          className="modalList"
          ref={provided.innerRef}
          {...provided.droppableProps}>
          {this.state.modalList.map((item, index) => (
            <Draggable draggableId={item.name} index={index} key={item.name}>
              {(provided) => (
                <div
                  className="modal"
                  key={item.name}
                  ref={provided.innerRef}
                  {...provided.draggableProps}
                  {...provided.dragHandleProps}>
                  <img src={item.imgUrl} alt="" />
                  <span title={item.wording}>{item.wording}</span>
                </div>
              )}
            </Draggable>
          ))}
          {provided.placeholder}
        </div>
      )}
    </Droppable>
  </div>
</DragDropContext>

可以看到,我在最外层的 .myModal div盒子套了一层 DragDropContext 作为容器;
Droppable 在我包裹map的.modalList 之外;
最内部则是每一个可以拖拽的实例modal,它是被 map > Draggable > modal 这样一层层包裹。

注意事项

  1. DragDropContext 可选五个函数作为参数

    <DragDropContext
    onBeforeCapture={this.onBeforeCapture}
    onBeforeDragStart={this.onBeforeDragStart}
    onDragStart={this.onDragStart}
    onDragUpdate={this.onDragUpdate}
    onDragEnd={this.onDragEnd} />

    写好了上面的结构,必须在onDragEnd回调中告诉react,用户拖拽的改变结果。也就是传递改变后的state给react,否则拖拽在松开鼠标后会恢复到拖拽前的顺序。
    以下是我onDragEnd的函数参考。

    // 拖拽调整顺序
    onDragEnd = (result) => {
        const sourceIndex = result.source.index;
        const destinationIndex = result.destination.index;
        if (sourceIndex === destinationIndex) {
          return;
        }
        const userList = deepClone(this.state.modalList);
        const [draggedItem] = userList.splice(sourceIndex, 1);
        userList.splice(destinationIndex, 0, draggedItem);
        this.setState({
          modalList: userList,
    	});
    };
    

    onDragEnd是一个对象,它会传递一些信息让我们利用。

    {
        "draggableId": "leetCode",
        "type": "DEFAULT",
        "source": {
            "index": 1,
            "droppableId": "mymodal"
        },
        "reason": "DROP",
        "mode": "FLUID",
        "destination": {
            "droppableId": "mymodal",
            "index": 2
        },
        "combine": null
    }
    

    其中最重要的是源位置(source)和目标位置(destination),里面有我们原来的位置和拖拽最终所在的位置,我们利用这两个index拿到源item并调整到目的位置。
    最后记得setState

  2. DroppableDraggable结构的props
    第二层结构需要添加 droppableId 和 方向,水平为horizontal,竖直方向为vertical
    <Droppable droppableId="mymodal" direction="horizontal">
    第三层结构需要添加 draggableId 和 index 以及 key,这几个都是用于区分不同项的手段。
    draggableId={item.name} index={index} key={item.name}

  3. DroppableDraggable结构内包的 箭头函数 及 div内的参数
    二层和三层包裹的必须是一个返回原本html结构的 函数, provided是官方提供的参数,里面包含着拖拽一系列参数,事件监听等。
    div内的参数为固定写法,照抄即可。

    第二层 div
    ref={provided.innerRef}
    {…provided.droppableProps}
    第三层 div
    ref={provided.innerRef}
    {…provided.draggableProps}
    {…provided.dragHandleProps}

  4. 最后,在map结束到 Droppable结束 之间的位置放一个{provided.placeholder},用于为拖动的元素占位。
    以上提到的一些参数属于必写,不写就会有error或者bug。
    感谢开源项目避免了让我花费时间造轮子,最后放一下这个依赖的github地址。
    atlassian/react-beautiful-dnd

原文链接:https://juejin.cn/post/7327479054953480231 作者:sakihomura

(0)
上一篇 2024年1月25日 上午10:16
下一篇 2024年1月25日 上午10:28

相关推荐

发表评论

登录后才能评论