react-beautiful-dnd踩坑记录

2,487 阅读3分钟

前言:本文主要详述一下在使用过程遇到的难点,对于插件的基本使用方法不赘述了,具体可参照

官网:github.com/atlassian/r…

使用demo:github.com/weihuayao/r…

1.react-beautiful-dnd在滚动区域内拖拽拖拽到底部闪动

需求:在固定高度区域内进行拖拽,如果列表过多,拖动时候会出现滚动条,当拖动到最后一个位置时候,原本最后一位需要上移动,但是此时会属于滚动过程中,所以现象是,dnd把dom上移后,滚动条会马上把dom拽下来(俩人开始不分伯仲的打架),然后就导致拖到最底部时候最后一个dom会频繁闪烁。

解决办法:思路是在监察拖动状态,如果是拖动过程中,在最底部多塞一个空白dom(非拖拽型),拖拽结束后去掉dom

react+hook写法的bugfix代码:

image.png

2.react-beautiful-dnd蛇形展示,拖动结束后放置错位

需求:为保证页面内用户更多的概览所有数据,所以从单列展示改为双列展示,具体实现是用flex布局,非常顺滑的实现了序号1和2为第一行,3和4第二行依次类推的展示形式,拖拽起来也很顺滑,不仔细看的话喜大普奔,但是仔细一看发现 “往上移动不能移动到右侧, 往下移动不能移动到左侧”

原因是: react-beautiful-dnd并没有很好的实现这种折行展示的形式,他提供的是多个列表间拖拽,但是我们的数据是顺序展示的,如果要分隔的话,需要把原始数据按奇偶分开,拖拽删除之类的操作都要去对比原始数据等等,本质上我们是想作为一组数据进行处理的,所以使用的flex进行折行展示,然后react-beautiful-dnd还是按一行处理,所以导致了以上问题。

解决办法:判断用户最后停留的位置是哪里,然后手动去更改目的地的坐标

这个处理起来还真挺麻烦的,我们需要去判断拖拽即将结束时候,用户的“目的地”是哪里,在拖拽过程中可以通过 Draggable 内的snapshot.isDragging 来判断 实时位置可以通过 provided.draggableProps.style.transform 来拿到,这里又有一个小坑,这个最后拖拽松手后落地后的状态是最后实际放置的位置,并不是最后的停留位置,所以我们需要一个数组来放置运动轨迹

const specilMove: MoveInfo = {
  translateX: [],
  translateY: []
}

这里边还有一个点是,这个轨迹是频繁触发,而且手指自我感觉不动(实际触板感觉动了)这个时候也是频繁触发一样的轨迹数据,所以我们记录的时候只需要记录一次,这里我一开始的做法是数组去重,但是发现有点不对,会把之前走过的数据,清除掉,所以只需要跟上一次记录做对比即可,

  const getMoveData = (transform, index) => {
    const curx = transform?.split('(')[1].split(',')[0].split('px')[0]
    const cury = transform?.split(',')[1].split('px')[0].split(' ')[1]
    const tempX = specilMove.translateX
    const tempY = specilMove.translateY
    if (curx !== tempX[tempX.length - 1] && curx) tempX.push(curx)
    if (cury !== tempY[tempY.length - 1] && cury) tempY.push(cury)
    // 记录拖拽轨迹,重复轨迹过滤
    specilMove.curNum = index
    specilMove.translateX = tempX
    specilMove.translateY = tempY
  }

记录到轨迹后,再去解决

““往上移动不能移动到右侧, 往下移动不能移动到左侧””

根据数据判断是落在左侧还是右侧,更改落脚点的坐标即可

至此踩坑告一段落,有相关问题的伙伴欢迎随时交流