>  기사  >  웹 프론트엔드  >  React-dnd가 드래그 앤 드롭을 구현하는 방법

React-dnd가 드래그 앤 드롭을 구현하는 방법

WBOY
WBOY원래의
2022-04-29 16:49:582969검색

구현 방법: 1. "import{DndProvider}from 'react-dnd'"를 사용하여 드래그 가능한 범위를 정의합니다. 2. "import{useDrag}from 'react-dnd'"를 사용하여 구성 요소 주위에 DragSource를 래핑합니다. 드래그할 수 있습니다.

React-dnd가 드래그 앤 드롭을 구현하는 방법

이 튜토리얼의 운영 환경: Windows 10 시스템, 반응 버전 17.0.1, Dell G3 컴퓨터.

react-dnd로 드래그 앤 드롭을 구현하는 방법

React DnD는 React 및 Redux의 핵심 작성자인 Dan Abramov가 만든 React 고차원 구성 요소 집합으로, 복잡한 드래그 앤 드롭 인터페이스를 구축하는 데 도움을 줄 수 있습니다. 구성 요소를 분리하여 유지합니다.

React DnD 요구 사항

  • 기본적으로 HTML5 드래그 앤 드롭 API를 사용하지만

  • DOM을 직접 운영하지 않음

  • DOM 및 드래그 앤 드롭 소스 및 타겟 디커플링

  • 을 지원합니다.

    HTML5 드래그 앤 드롭으로 유형 일치 및 데이터 전달 아이디어를 훔치는 통합

React DnD의 특징

기성 구성 요소를 제공하지 않고 드래그 앤 드롭에 집중

React DnD가 제공하는 것 강력한 프리미티브 세트이지만 기성 컴포넌트를 포함하지 않고 사용자 컴포넌트를 래핑하고 소품을 주입합니다. jQuery UI 등보다 낮은 수준으로 드래그 앤 드롭 상호 작용을 올바르게 만드는 데 중점을 두고 좌표 제한과 같은 시각적 효과를 사용자에게 맡깁니다. 이는 실제로 우려 사항 분리의 원칙입니다. 예를 들어 React DnD는 정렬 가능한 구성 요소를 제공할 의도가 없지만 사용자는 이를 기반으로 필요한 사용자 정의 정렬 가능한 구성 요소를 빠르게 개발할 수 있습니다.

단방향 데이터 흐름

React와 유사하게 선언적 렌더링을 채택하고 redux와 같은 단방향 데이터 흐름 아키텍처를 사용합니다. 실제로 Redux는 내부적으로 사용됩니다

플랫폼의 기본 API 문제를 숨깁니다

HTML5 드래그 앤 드롭 API는 문제점과 브라우저 불일치로 가득 차 있습니다. React DnD는 이를 내부적으로 처리하므로 소비자는 브라우저 문제를 해결하는 대신 애플리케이션 개발에 집중할 수 있습니다.

확장 가능하고 테스트 가능

React DnD는 기본적으로 HTML5 드래그 앤 드롭 API 래퍼를 제공하지만 사용자 정의 "백엔드"를 제공할 수도 있습니다. 터치 이벤트, 마우스 이벤트 또는 기타 사항을 기반으로 사용자 지정 DnD 백엔드를 만들 수 있습니다. 예를 들어, 내장된 모의 백엔드를 사용하면 노드 환경에서 구성 요소의 드래그 앤 드롭 상호 작용을 테스트할 수 있습니다.

미래 준비

React DnD는 믹스인을 내보내지 않으며 ES6 클래스, createReactClass 또는 기타 React 프레임워크를 사용하여 생성된 모든 구성 요소와 동일하게 작동합니다. 그리고 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. , 호환되는 항목을 드래그하거나 가리키거나 놓을 때 반응하도록 만드세요.

/*
 * @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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.