ホームページ > ウェブフロントエンド > jsチュートリアル > React dnd-kit、ソート可能なツリーリストのドラッグアンドドロップを実装

React dnd-kit、ソート可能なツリーリストのドラッグアンドドロップを実装

Susan Sarandon
リリース: 2024-12-10 20:09:10
オリジナル
581 人が閲覧しました

こんにちは、王富鵬です。

私はシニア フルスタック エンジニアで、17.5k のオープンソース プロジェクト PMP の作成者です。現在、Notion スタイルのナレッジ ベースを開発しています
React Nextjs と Supabase を使用した、AI の作成とコラボレーションを含む HuashuiAI。

この記事では、React と dnd-kit でソート可能なツリーリストのドラッグ アンド ドロップを実装する方法を共有します。ソース コードのリンクはこの記事の下部にあります。

React   dnd-kit, implement tree-list drag and drop sortable

DND キットとソート可能なコンポーネント

Dnd-kit は React エコシステムの一般的なドラッグ ドロップ ツールであり、デフォルトで並べ替え可能をサポートしています。

    <DndContext 
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
      <SortableContext 
        items={items}
        strategy={verticalListSortingStrategy}
      >
        {items.map(id => <SortableItem key={id}>



<p>But it can only support the one-level list. If we want to implement a multi-level nested list (or tree), we have to customize it.</p>

<h2>
  
  
  Define state date structure
</h2>

<p>Modern front-end frameworks such as React Vue are data-driven views, so defining data structures first and then considering UI rendering.</p>

<p>The most common data structure definition for multi-level nested lists (trees) is as follows, and virtual DOM vnode is also defined in this way.<br>
</p>

<pre class="brush:php;toolbar:false">const defaultItems = [
  { id: 'A', children: [] },
  {
    id: 'B',
    children: [
      { id: 'B1', children: [] },
      {
        id: 'B2',
        children: [
          { id: 'B2a', children: [] },
          { id: 'B2b', children: [] },
        ],
      },
    ],
  },
  { id: 'C', children: [] },
  {
    id: 'D',
    children: [
      { id: 'D1', children: [] },
      { id: 'D2', children: [] },
    ],
  },
  { id: 'E', children: [] },
]
ログイン後にコピー

マルチレベルのネストされた SortableContext は実現できません

状態データ構造はネストされているため、最初に思いつくのは、UI 構造をネストして一緒にレンダリングすることです。

まず、 をネストします。 内、これは 1 層リストに使用されるのと同じ方法です。

React   dnd-kit, implement tree-list drag and drop sortable

次に、下位の のネストを続けます。 内子を表示します。

React   dnd-kit, implement tree-list drag and drop sortable

ランニング効果は以下の通りです。問題は、同じレベル内ではドラッグ アンド ドロップによる並べ替えが許可されているが、レベル間の並べ替えはコンテキストではないため不可能であることです。これは合理的です

React   dnd-kit, implement tree-list drag and drop sortable

マルチレベルからシングルレベルへの変換が可能

ネストは実現できないため、複数のレベルを単一のレベルに変換する必要があります。

ただし、最初に階層の深さを表示し、次にそのアイテムにどのような親ノードがあるかを知るために、各項目にancestorIds 属性を追加する必要があります。

interface IItem {
  id: string
  ancestorIds?: string[]
  children?: IItem[]
}

function flatten(items: IItem[]): IItem[] {
  return items.reduce<IItem[]>((acc, item) => {
    acc.push(item)
    if (item.children) {
      const children = item.children.map((i) => ({
        ...i,
        ancestorIds: [...(item.ancestorIds || []), item.id], // add ancestorIds
      }))
      acc.push(...flatten(children))
    }
    return acc
  }, [])
}
ログイン後にコピー

変換後のレンダリング効果は次のようになり、ドラッグして並べ替えることができるようになりました。ただし、状態の並べ替えが変更されるまでは有効になりません。

React   dnd-kit, implement tree-list drag and drop sortable

さらに、ancestorID の階層関係を通じて移動できるかどうかを判断することもできます。親ノードを子ノードに移動することはできません。移動しないと、ループが停止します。

たとえば、上の図で、B2 を B2a の位置にドラッグすると、B2a の先祖 ID に B2 が含まれていることがわかります。項目をその下位にドラッグできないため、これは不可能です。

状態データを変更する

操作を容易にするために、データは Zustand グローバル ストアに配置されます。

React   dnd-kit, implement tree-list drag and drop sortable

Dnd-kit は、ドラッグされた要素を activeItem として参照し、配置されたターゲットの位置を overItem として参照します。したがって、状態データを変更するということは、activeItem を overItem の位置に移動することを意味します。

単一レベルの場合、Dnd-kit は直接変更できるメソッド arrayMove を提供します。ドキュメントリンク https://docs.dndkit.com/presets/sortable

React   dnd-kit, implement tree-list drag and drop sortable

しかし、複数レベルのネストされたリスト (ツリー) では、自分で実装する必要があり、少し面倒です。コア コードはここにあります。参照用にソース コード (記事の最後にあります) をダウンロードできます。

React   dnd-kit, implement tree-list drag and drop sortable

問題が発生しました

下の図に示すように、A を B の下にドラッグすると、A は B 内ではなく、全体として B の下に移動します。

React   dnd-kit, implement tree-list drag and drop sortable

この問題を解決するには、B の後に B の子要素があるかどうかを判断する必要があります。存在する場合は、その子要素に overItem を割り当てます

React   dnd-kit, implement tree-list drag and drop sortable

次に、現在のアクティブな要素を項目の最初の要素に挿入します。

React   dnd-kit, implement tree-list drag and drop sortable

終わり

ソースコードのリンクはこちら https://github.com/wangfupeng1988/react-dnd-sortable-demo

ところで、私は国際的な仕事の機会を探しています。機会があれば、私の Github プロフィールに連絡してください。

以上がReact dnd-kit、ソート可能なツリーリストのドラッグアンドドロップを実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート