実装方法: 1. 「import{DndProvider}from 'react-dnd'」を使用してドラッグ可能な範囲を定義します; 2. 「import{useDrag}from 'react-dnd'」を使用して DragSource Just をラップしますコンポーネントをドラッグできるように保持します。
このチュートリアルの動作環境: Windows 10 システム、react17.0.1 バージョン、Dell G3 コンピューター。
React DnD は、React と Redux の中心的な作成者である Dan Abramov によって作成された React の高次コンポーネントのセットであり、複雑なコンポーネントを分離しながら、インターフェイスをドラッグ アンド ドロップします。
#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: 'flex' }}>
<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;
/* * @Author: muge * @Date: 2021-12-07 14:26:08 * @LastEditors: Please set LastEditors * @LastEditTime: 2021-12-08 14:18:52 */ import { useDrag } from 'react-dnd'; const ItemTypes = { BOX: 'box', }; const style = { border: '1px dashed gray', backgroundColor: 'white', padding: '0.5rem 1rem', marginRight: '1rem', marginBottom: '1rem', cursor: 'move', }; 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, 'monitor131'); 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;
/* * @Author: muge * @Date: 2021-12-07 14:26:08 * @LastEditors: Please set LastEditors * @LastEditTime: 2021-12-08 14:33:08 */ import React from 'react'; import { useDrop } from 'react-dnd'; const ItemTypes = { BOX: 'box', }; const style: any = { border: '1px solid gray', height: '15rem', width: '15rem', padding: '2rem', textAlign: 'center', }; 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, 'item'); // console.log(monitor, 'monitor'); // }, })); // console.log(isOver, 'isOver'); // console.log(canDrop, 'canDrop'); return ( <div ref={drop} style={style}> {isActive ? 'Release to drop' : 'Drag item here'} <div style={{ backgroundColor: 'pink', height: 30, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 17, fontWeight: 600, width: '100%', }} > {JSON.stringify(currentList) !== '{}' ? JSON.stringify(currentList) : '当前item'} </div> </div> ); }; export default TargetBox;
react ビデオ チュートリアル
」以上がReact-dnd がドラッグ アンド ドロップを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。