ホームページ  >  記事  >  ウェブフロントエンド  >  React-dnd がドラッグ アンド ドロップを実装する方法

React-dnd がドラッグ アンド ドロップを実装する方法

WBOY
WBOYオリジナル
2022-04-29 16:49:583031ブラウズ

実装方法: 1. 「import{DndProvider}from 'react-dnd'」を使用してドラッグ可能な範囲を定義します; 2. 「import{useDrag}from 'react-dnd'」を使用して DragSource Just をラップしますコンポーネントをドラッグできるように保持します。

React-dnd がドラッグ アンド ドロップを実装する方法

このチュートリアルの動作環境: Windows 10 システム、react17.0.1 バージョン、Dell G3 コンピューター。

react-dnd を使用してドラッグ アンド ドロップを実装する方法

React DnD は、React と Redux の中心的な作成者である Dan Abramov によって作成された React の高次コンポーネントのセットであり、複雑なコンポーネントを分離しながら、インターフェイスをドラッグ アンド ドロップします。

#React DnD の要件

  • デフォルトで HTML5 ドラッグ アンド ドロップ API を使用しますが、

    ## をサポートします

  • #DOM を直接操作しないでください
  • ##DOM とドラッグ アンド ドロップのソースとターゲットの分離
  • スチールを組み込むHTML5 にドラッグ アンド ドロップで入力 マッチングとデータ受け渡しに関するアイデア
  • ##React DnDの特徴

##ドラッグ アンド ドロップに重点を置き、既製のコンポーネントは不要

React DnD は強力なプリミティブのセットを提供しますが、既製のコンポーネントは含まれておらず、代わりにユーザーのコンポーネントをラップして props を挿入します。 。 jQuery UIなどよりも低レベルであり、ドラッグアンドドロップ操作を正しくすることに重点を置き、座標制限などの視覚効果をユーザーに委ねます。これは実際には関心の分離の原則であり、たとえば、React DnD は並べ替え可能なコンポーネントを提供することを意図していませんが、ユーザーはこれに基づいて必要なカスタムの並べ替え可能なコンポーネントを迅速に開発できます。

一方向データフロー

Reactと同様の宣言型レンダリングを採用し、reduxのような一方向データフローアーキテクチャを採用、実際に内部ではReduxを使用しています

プラットフォームの基盤となる API に関する問題を隠す

HTML5 ドラッグ アンド ドロップ API には落とし穴とブラウザの不一致がたくさんあります。 React DnD はそれらを内部で処理するため、ユーザーはブラウザの問題を解決するのではなく、アプリケーションの開発に集中できます。

拡張性とテスト可能

React DnD は、デフォルトで HTML5 ドラッグ アンド ドロップ API ラッパーを提供しますが、カスタムの「バックエンド」を提供することもできます。タッチ イベント、マウス イベント、またはその他のものに基づいてカスタム DnD バックエンドを作成できます。たとえば、組み込みのモック バックエンドを使用すると、ノード環境でコンポーネントのドラッグ アンド ドロップ操作をテストできます。

将来に備えて

React DnD はミックスインをエクスポートせず、ES6 クラス、createReactClass、またはその他の React フレームワーク Created を使用するかどうかに関係なく、どのコンポーネントでも同様に機能します。また、API は ES7 デコレータをサポートしています。

例は次のとおりです:

1.1. DndProvider を使用してドラッグ可能な範囲を定義します

/*
 * @Author: muge
 * @Date: 2021-12-04 16:59:25
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-12-08 14:24:47
 */
import React, { useState } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import SourceBox from './SourceBox';
import TargetBox from './TargetBox';
import TreeBox from './TreeBox';
const item: any[] = [
  {
    id: 1,
    name: 'muge',
  },
  {
    id: 2,
    name: 'muxi',
  },
  {
    id: 3,
    name: 'mugege',
  },
];
const Container = () => {
  // 当前拖拽项
  const [currentList, setCurrentList] = useState<any>({});
  return (
    // 类似redux数据传输  需要在最外层包裹对象
    <DndProvider backend={HTML5Backend}>
      <h1>拖拽源组件 列表-----树</h1>
      <div style={{ display: &#39;flex&#39; }}>
        <div>
          {/* 列表拖拽源 */}
          {item.map((itemz: any, index: number) => (
            <SourceBox setCurrentList={setCurrentList} item={itemz} key={index} />
          ))}
        </div>
        {/* 注意,不要树组件整体直接设置拖拽,抽成一个组件来遍历每一项 =》自定义渲染*/}
        {/* 树形拖拽源 */}
        <TreeBox />
      </div>
      <h1>拖拽放置目标</h1>
      {/* 拖拽最终放置组件 */}
      <TargetBox currentList={currentList} />
    </DndProvider>
  );
};
export default Container;
2. DragSource パッケージを使用しますドラッグできるようにコンポーネントをラップします
/*
 * @Author: muge
 * @Date: 2021-12-07 14:26:08
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-12-08 14:18:52
 */
import { useDrag } from &#39;react-dnd&#39;;
const ItemTypes = {
  BOX: &#39;box&#39;,
};
const style = {
  border: &#39;1px dashed gray&#39;,
  backgroundColor: &#39;white&#39;,
  padding: &#39;0.5rem 1rem&#39;,
  marginRight: &#39;1rem&#39;,
  marginBottom: &#39;1rem&#39;,
  cursor: &#39;move&#39;,
};
const SourceBox = ({ item, setCurrentList }: any) => {
  const [{ opacity }, drag] = useDrag(
    () => ({
      type: ItemTypes.BOX,
      collect: (monitor) => ({
        opacity: monitor.isDragging() ? 0.4 : 1,
      }),
      item: () => item, //返回当前列表项数据
      canDrag: (monitor) => {
        //是否取消拖拽
        console.log(monitor, &#39;monitor131&#39;);
        return true;
      },
      //
      end(currentItem, monitor) {
        // monitor.getDropResult(); //获取拖拽对象所处容器的数据
        // monitor.didDrop(); // 当前容器能否放置拖拽对象 拖动停止时触发
        monitor.didDrop() && setCurrentList(currentItem); //在容器点松开 才赋值
      },
    }),
    [],
  );
  return (
    <div ref={drag} style={{ ...style, opacity }}>
      {item.id}------{item.name}
    </div>
  );
};
export default SourceBox;

3. DropTarget を使用してコンポーネントをラップし、互換性のあるアイテムのドラッグ、ホバリング、またはドロップに反応できるようにします。

/*
 * @Author: muge
 * @Date: 2021-12-07 14:26:08
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-12-08 14:33:08
 */
import React from &#39;react&#39;;
import { useDrop } from &#39;react-dnd&#39;;
const ItemTypes = {
  BOX: &#39;box&#39;,
};
const style: any = {
  border: &#39;1px solid gray&#39;,
  height: &#39;15rem&#39;,
  width: &#39;15rem&#39;,
  padding: &#39;2rem&#39;,
  textAlign: &#39;center&#39;,
};
const TargetBox = ({ currentList }: any) => {
  const [{ isActive, isOver, canDrop }, drop] = useDrop(() => ({
    accept: ItemTypes.BOX,
    collect: (monitor) => ({
      isActive: monitor.canDrop() && monitor.isOver(),
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
    // hover: (item, monitor) => {
    //   console.log(item, &#39;item&#39;);
    //   console.log(monitor, &#39;monitor&#39;);
    // },
  }));
  // console.log(isOver, &#39;isOver&#39;);
  // console.log(canDrop, &#39;canDrop&#39;);
  return (
    <div ref={drop} style={style}>
      {isActive ? &#39;Release to drop&#39; : &#39;Drag item here&#39;}
      <div
        style={{
          backgroundColor: &#39;pink&#39;,
          height: 30,
          display: &#39;flex&#39;,
          alignItems: &#39;center&#39;,
          justifyContent: &#39;center&#39;,
          fontSize: 17,
          fontWeight: 600,
          width: &#39;100%&#39;,
        }}
      >
        {JSON.stringify(currentList) !== &#39;{}&#39; ? JSON.stringify(currentList) : &#39;当前item&#39;}
      </div>
    </div>
  );
};
export default TargetBox;

このリストにドラッグ アンド ドロップして完了します

推奨される学習: 「

react ビデオ チュートリアル

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

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。