Convert Figma logo to code with AI

react-dnd logoreact-dnd

Drag and Drop for React

20,973
1,989
20,973
449

Top Related Projects

Beautiful and accessible drag and drop for lists with React

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

A draggable and resizable grid layout with responsive breakpoints, for React.

🖱 A resizable and draggable component for React.

Drag-and-drop sortable component for nested data and hierarchies

Simple HTML5 drag-drop zone with React.js.

Quick Overview

React DnD is a popular drag and drop library for React applications. It provides a set of React hooks and components to implement complex drag and drop interfaces with ease. The library is highly customizable and can be used to create a wide range of interactive user interfaces.

Pros

  • Flexible and powerful API for implementing drag and drop functionality
  • Excellent performance due to its use of React's reconciliation process
  • Supports both mouse and touch events, making it suitable for desktop and mobile applications
  • Extensive documentation and community support

Cons

  • Steep learning curve for beginners due to its abstract concepts
  • Can be overkill for simple drag and drop implementations
  • Requires additional setup and configuration compared to some simpler alternatives
  • May have compatibility issues with certain React versions or other libraries

Code Examples

  1. Basic drag and drop setup:
import { useDrag, useDrop } from 'react-dnd'

function DraggableItem({ id, text }) {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: 'ITEM',
    item: { id },
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
  }))

  return (
    <div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {text}
    </div>
  )
}

function DropTarget({ onDrop }) {
  const [{ isOver }, drop] = useDrop(() => ({
    accept: 'ITEM',
    drop: (item) => onDrop(item.id),
    collect: (monitor) => ({
      isOver: !!monitor.isOver(),
    }),
  }))

  return (
    <div ref={drop} style={{ background: isOver ? 'lightblue' : 'white' }}>
      Drop here
    </div>
  )
}
  1. Custom drag preview:
import { useDrag } from 'react-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'

function DraggableWithCustomPreview({ id, text }) {
  const [, drag, preview] = useDrag(() => ({
    type: 'ITEM',
    item: { id, text },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }))

  useEffect(() => {
    preview(getEmptyImage(), { captureDraggingState: true })
  }, [preview])

  return <div ref={drag}>{text}</div>
}
  1. Drag handles:
import { useDrag } from 'react-dnd'

function DraggableWithHandle({ id, text }) {
  const [, drag] = useDrag(() => ({
    type: 'ITEM',
    item: { id },
  }))

  return (
    <div>
      <span ref={drag} style={{ cursor: 'move' }}></span>
      {text}
    </div>
  )
}

Getting Started

  1. Install the package:

    npm install react-dnd react-dnd-html5-backend
    
  2. Wrap your app with the DndProvider:

    import { DndProvider } from 'react-dnd'
    import { HTML5Backend } from 'react-dnd-html5-backend'
    
    function App() {
      return (
        <DndProvider backend={HTML5Backend}>
          {/* Your app components */}
        </DndProvider>
      )
    }
    
  3. Start using the drag and drop hooks in your components as shown in the code examples above.

Competitor Comparisons

Beautiful and accessible drag and drop for lists with React

Pros of react-beautiful-dnd

  • Easier to use and set up, with a more intuitive API
  • Better performance for larger lists and complex drag operations
  • Provides smooth animations and visual feedback out of the box

Cons of react-beautiful-dnd

  • Less flexible for custom drag-and-drop scenarios
  • Limited to vertical and horizontal lists, no support for free-form dragging
  • Larger bundle size compared to react-dnd

Code Comparison

react-beautiful-dnd:

<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <ul {...provided.droppableProps} ref={provided.innerRef}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {(provided) => (
              <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                {item.content}
              </li>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </ul>
    )}
  </Droppable>
</DragDropContext>

react-dnd:

const [{ isDragging }, drag] = useDrag({
  type: 'ITEM',
  item: { id, index },
  collect: (monitor) => ({
    isDragging: monitor.isDragging(),
  }),
});

return (
  <li ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
    {item.content}
  </li>
);

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Pros of react-sortable-hoc

  • Simpler API and easier to implement for basic sorting scenarios
  • Built-in support for touch devices and auto-scrolling
  • Lightweight and focused specifically on sortable functionality

Cons of react-sortable-hoc

  • Less flexible for complex drag and drop interactions beyond sorting
  • Limited customization options compared to react-dnd
  • Smaller community and ecosystem

Code Comparison

react-sortable-hoc:

import { SortableContainer, SortableElement } from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) => <li>{value}</li>);

const SortableList = SortableContainer(({items}) => (
  <ul>
    {items.map((value, index) => (
      <SortableItem key={`item-${index}`} index={index} value={value} />
    ))}
  </ul>
));

react-dnd:

import { useDrag, useDrop } from 'react-dnd';

const DraggableItem = ({id, text, index, moveItem}) => {
  const [, drag] = useDrag({ type: 'ITEM', item: { id, index } });
  const [, drop] = useDrop({
    accept: 'ITEM',
    hover: (draggedItem) => {
      if (draggedItem.index !== index) {
        moveItem(draggedItem.index, index);
        draggedItem.index = index;
      }
    },
  });

  return <div ref={(node) => drag(drop(node))}>{text}</div>;
};

A draggable and resizable grid layout with responsive breakpoints, for React.

Pros of react-grid-layout

  • Specialized for grid-based layouts, offering a more streamlined solution for grid systems
  • Built-in responsive features, making it easier to create layouts that adapt to different screen sizes
  • Includes a resizable grid system out of the box, simplifying the process of creating adjustable layouts

Cons of react-grid-layout

  • Less flexible for non-grid-based drag and drop interactions
  • Limited to rectangular grid items, which may not suit all layout requirements
  • Steeper learning curve for developers unfamiliar with grid-based systems

Code Comparison

react-grid-layout:

import GridLayout from 'react-grid-layout';

<GridLayout
  className="layout"
  layout={layout}
  cols={12}
  rowHeight={30}
  width={1200}
>
  {children}
</GridLayout>

react-dnd:

import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

<DndProvider backend={HTML5Backend}>
  <YourDraggableComponent />
  <YourDroppableComponent />
</DndProvider>

react-dnd offers a more generic approach, allowing for diverse drag and drop interactions, while react-grid-layout provides a specialized solution for grid-based layouts with built-in responsiveness and resizing capabilities.

🖱 A resizable and draggable component for React.

Pros of react-rnd

  • Simpler API for resizing and dragging components
  • Built-in support for both dragging and resizing
  • Lightweight and focused on a specific use case

Cons of react-rnd

  • Less flexible for complex drag-and-drop scenarios
  • Limited to resizing and dragging within a container
  • Fewer customization options for drag behavior

Code Comparison

react-rnd:

<Rnd
  default={{
    x: 0,
    y: 0,
    width: 320,
    height: 200,
  }}
>
  Resizable and draggable component
</Rnd>

react-dnd:

<DndProvider backend={HTML5Backend}>
  <DragSource>
    <DropTarget>
      <YourComponent />
    </DropTarget>
  </DragSource>
</DndProvider>

react-rnd provides a more straightforward API for creating resizable and draggable components, while react-dnd offers a more flexible and powerful system for implementing complex drag-and-drop interactions. react-rnd is better suited for simpler use cases where you need quick implementation of resizable and draggable elements. react-dnd, on the other hand, excels in scenarios requiring advanced drag-and-drop functionality, custom drag sources and drop targets, and more granular control over the drag-and-drop process.

Drag-and-drop sortable component for nested data and hierarchies

Pros of react-sortable-tree

  • Specialized for tree structures, making it easier to implement hierarchical drag-and-drop
  • Includes built-in tree visualization and management features
  • Simpler API for common tree operations like adding, removing, and moving nodes

Cons of react-sortable-tree

  • Less flexible for non-tree drag-and-drop scenarios
  • More opinionated structure, which may not fit all use cases
  • Smaller community and potentially less frequent updates

Code Comparison

react-dnd:

import { useDrag, useDrop } from 'react-dnd';

function DraggableItem({ id, text }) {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: 'ITEM',
    item: { id },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }));

  return <div ref={drag}>{text}</div>;
}

react-sortable-tree:

import SortableTree from 'react-sortable-tree';

function TreeComponent({ treeData, onChange }) {
  return (
    <SortableTree
      treeData={treeData}
      onChange={onChange}
      generateNodeProps={({ node }) => ({
        title: node.name,
      })}
    />
  );
}

The code comparison shows that react-dnd requires more setup for basic drag-and-drop functionality, while react-sortable-tree provides a more declarative API specifically for tree structures.

Simple HTML5 drag-drop zone with React.js.

Pros of react-dropzone

  • Specialized for file uploads and drag-and-drop functionality
  • Simpler API for handling file drops and uploads
  • Lightweight and focused on a specific use case

Cons of react-dropzone

  • Limited to file upload scenarios
  • Less flexible for general drag-and-drop interactions
  • Fewer customization options for complex drag-and-drop behaviors

Code Comparison

react-dropzone:

import React from 'react';
import {useDropzone} from 'react-dropzone';

function MyDropzone() {
  const {getRootProps, getInputProps} = useDropzone();
  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </div>
  );
}

react-dnd:

import React from 'react';
import { useDrag, useDrop } from 'react-dnd';

function DraggableItem() {
  const [, drag] = useDrag(() => ({ type: 'ITEM' }));
  return <div ref={drag}>Drag me</div>;
}

function DropTarget() {
  const [, drop] = useDrop(() => ({ accept: 'ITEM' }));
  return <div ref={drop}>Drop here</div>;
}

react-dnd offers a more general-purpose solution for implementing drag-and-drop functionality, allowing for complex interactions between draggable elements and drop targets. It provides greater flexibility and control over the drag-and-drop behavior but requires more setup and configuration. react-dropzone, on the other hand, is specifically designed for file uploads and offers a simpler API for this particular use case, making it easier to implement file drop zones with less code.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

npm version npm downloads Build Status codecov Dependabot Status

React DnD

Drag and Drop for React.

See the docs, tutorials and examples on the website:

http://react-dnd.github.io/react-dnd/

See the changelog on the Releases page:

https://github.com/react-dnd/react-dnd/releases

Questions? Find us on the Reactiflux Discord Server (#need-help)

https://www.reactiflux.com/

Shoutouts 🙏

BrowserStack Logo

Big thanks to BrowserStack for letting the maintainers use their service to debug browser issues.

NPM DownloadsLast 30 Days