返回

React Beautiful DnD 踩坑记录:解决拖动到边缘闪烁和折行后错位问题

前端

前言

React Beautiful DnD 是一个流行的 React 库,用于构建拖放列表。它提供了一个灵活、可定制的 API,使开发人员可以轻松地创建交互式拖放界面。然而,在使用该库的过程中,我遇到了几个常见的陷阱,导致拖动行为异常。在这篇文章中,我将分享这些问题以及我找到的解决方案。

问题 1:拖动到边缘闪烁

当项目被拖动到列表边缘时,我遇到了一个闪烁的问题。每当项目接近边缘时,它就会快速闪烁,影响用户体验。

解决方案

闪烁问题是由 React Beautiful DnD 中的滚动行为引起的。当项目被拖动到列表边缘时,库会自动滚动列表以显示更多项目。然而,这种滚动行为不流畅,导致闪烁。

为了解决这个问题,我禁用了自动滚动。我通过将 isScrollSensitive prop 设置为 false 来实现这一点。

import { DragDropContext } from 'react-beautiful-dnd';

const MyDnD = () => {
  return (
    <DragDropContext isScrollSensitive={false}>
      {/* ... */}
    </DragDropContext>
  );
};

禁用自动滚动后,闪烁问题消失了,拖动体验变得更加流畅。

问题 2:折行展示后拖动后落地位置异常

另一个我遇到的问题是,当项目在折行展示模式下拖动后,落地位置异常。当项目被拖动到另一个折行时,它会降落在错误的位置。

解决方案

这个问题是由 React Beautiful DnD 中的布局计算引起的。在折行展示模式下,库无法准确计算项目的位置。

为了解决这个问题,我实现了自定义布局计算器。我使用 onDragUpdate 回调函数来获取项目的当前位置,然后手动计算项目应该降落在哪个位置。

import { DragDropContext } from 'react-beautiful-dnd';

const MyDnD = () => {
  const [state, setState] = useState({ items: [...] });

  const onDragUpdate = (update) => {
    const { destination } = update;

    if (!destination) {
      return;
    }

    const sourceIndex = state.items.findIndex((item) => item.id === update.draggableId);
    const destinationIndex = state.items.findIndex((item) => item.id === destination.droppableId);

    // 计算目标位置
    const targetPosition = calculateTargetPosition(sourceIndex, destinationIndex);

    // 更新状态
    setState((prevState) => ({
      items: prevState.items.map((item, index) => {
        if (index === sourceIndex) {
          return { ...item, position: targetPosition };
        }

        return item;
      }),
    }));
  };

  return (
    <DragDropContext onDragUpdate={onDragUpdate}>
      {/* ... */}
    </DragDropContext>
  );
};

实现自定义布局计算器后,折行展示模式下拖动后的落地位置问题消失了,拖动体验变得更加准确。

结论

React Beautiful DnD 是一个强大的库,可以创建交互式拖放界面。然而,在使用过程中遇到一些问题是很常见的。通过了解这些陷阱并实施相应的解决方案,我们可以避免这些问题并构建流畅、无缝的拖放体验。

我希望这篇文章中分享的解决方案对其他遇到类似问题的开发人员有所帮助。如果您有任何其他问题或发现,请随时留言,我会尽我所能提供帮助。