WEBKT

React Hooks 实现拖拽排序列表?这些思路和库让开发事半功倍

78 0 0 0

在 React 应用中,拖拽排序列表是一个常见的需求,例如任务看板、可自定义排序的菜单等等。使用 React Hooks 可以更简洁、高效地实现这个功能。本文将深入探讨如何使用 React Hooks 实现一个拖拽排序列表,并推荐一些有用的库,让你的开发事半功倍。

实现思路:

  1. 状态管理: 使用 useState Hook 来管理列表数据。列表数据是一个数组,每个元素代表列表中的一项。
  2. 拖拽事件处理: 使用 onDragStartonDragOveronDragEnteronDragLeaveonDroponDragEnd 等事件来处理拖拽过程。这些事件需要绑定到列表的每个元素上。
  3. 拖拽状态: 使用 useRef Hook 来存储当前拖拽的元素的索引。useRef 可以在组件的整个生命周期中保持对值的引用,而不会触发重新渲染。
  4. 更新列表数据:onDrop 事件中,根据拖拽的起始索引和目标索引,更新列表数据。可以使用数组的 splice 方法来移动元素。

具体步骤:

  1. 初始化列表数据:
import React, { useState } from 'react';

const initialList = [
  { id: 1, text: 'Item 1' },
  { id: 2, text: 'Item 2' },
  { id: 3, text: 'Item 3' },
];

function SortableList() {
  const [list, setList] = useState(initialList);

  return (
    <ul>
      {list.map((item, index) => (
        <li key={item.id}>{item.text}</li>
      ))}
    </ul>
  );
}

export default SortableList;
  1. 添加拖拽事件处理函数:
import React, { useState, useRef } from 'react';

// ... (initialList and SortableList definition)

function SortableList() {
  const [list, setList] = useState(initialList);
  const dragItem = useRef(null);

  const handleDragStart = (e, index) => {
    dragItem.current = index;
    console.log("Dragging", index);
  };

  const handleDragEnter = (e, index) => {
    console.log("Entering", index);
  };

  const handleDragOver = (e) => {
    e.preventDefault(); // Necessary to allow dropping
  };

  const handleDrop = (e, index) => {
    console.log("Dropping", index);
  };

  return (
    <ul>
      {list.map((item, index) => (
        <li
          key={item.id}
          draggable
          onDragStart={(e) => handleDragStart(e, index)}
          onDragEnter={(e) => handleDragEnter(e, index)}
          onDragOver={handleDragOver}
          onDrop={(e) => handleDrop(e, index)}
        >
          {item.text}
        </li>
      ))}
    </ul>
  );
}

export default SortableList;
  1. 实现拖拽逻辑:
import React, { useState, useRef } from 'react';

// ... (initialList and SortableList definition)

function SortableList() {
  const [list, setList] = useState(initialList);
  const dragItem = useRef(null);
  const dragOverItem = useRef(null);

  const handleDragStart = (e, index) => {
    dragItem.current = index;
    console.log("Dragging", index);
  };

  const handleDragEnter = (e, index) => {
    dragOverItem.current = index;
    console.log("Entering", index);
  };

  const handleDragOver = (e) => {
    e.preventDefault(); // Necessary to allow dropping
  };

  const handleDrop = (e, index) => {
    const copyListItems = [...list];
    const dragItemContent = copyListItems[dragItem.current];
    copyListItems.splice(dragItem.current, 1);
    copyListItems.splice(dragOverItem.current, 0, dragItemContent);
    dragItem.current = null;
    dragOverItem.current = null;
    setList(copyListItems);
  };

  return (
    <ul>
      {list.map((item, index) => (
        <li
          style={{backgroundColor: dragOverItem.current === index ? 'lightblue' : 'white'}}
          key={item.id}
          draggable
          onDragStart={(e) => handleDragStart(e, index)}
          onDragEnter={(e) => handleDragEnter(e, index)}
          onDragOver={handleDragOver}
          onDrop={(e) => handleDrop(e, index)}
        >
          {item.text}
        </li>
      ))}
    </ul>
  );
}

export default SortableList;

库推荐:

  • react-beautiful-dnd 由 Atlassian 开发,提供美观、流畅的拖拽体验,适用于复杂的列表和看板。
  • react-sortablejs 基于 SortableJS 库,功能强大,支持多种拖拽排序场景,例如网格布局、嵌套列表等。
  • dnd-kit 一个轻量级的、高性能的拖拽工具包,提供了灵活的 API 和 hooks,可以让你构建高度定制化的拖拽体验。

代码解释:

  • dragItem.currentdragOverItem.current 使用 useRef 保存拖拽元素的 index。
  • handleDragStart 函数中,记录开始拖拽的元素的 index。
  • handleDragEnter 函数中,记录拖拽元素进入的元素的 index。
  • handleDragOver 函数中,阻止浏览器的默认行为,允许 drop 事件触发。
  • handleDrop 函数中,更新列表数据,将拖拽的元素移动到目标位置。
  • style 属性用于在拖拽元素经过时,改变背景颜色,提供视觉反馈。

注意事项:

  • e.preventDefault() 必须在 onDragOver 事件中调用,否则 onDrop 事件不会触发。
  • key 属性对于 React 列表的性能至关重要,确保每个列表项都有唯一的 key
  • 对于复杂的列表,可以考虑使用虚拟化技术来提高性能。

总结:

使用 React Hooks 可以方便地实现拖拽排序列表。理解拖拽事件的处理流程和状态管理是关键。选择合适的库可以简化开发,提高效率。希望本文能帮助你更好地掌握 React Hooks,并构建出更强大的拖拽排序功能。

进一步学习:

Hook队长 React Hooks拖拽排序列表组件

评论点评