React DnD in Examples

Artem Diashkin
Oct 7, 2020 · 8 min read

React DnD is a set of React utilities to help you build complex drag and drop interfaces . We will take a look on it’s basic capabilities with implementing our own kanban board.

What will be covered in this article:

  • Prerequisites
  • Installation
  • Implementing draggable item
  • Implementing droppable item
  • Creatin kanban board
  • Adding multiple draggable items
  • Make items sortable in the column
  • Mobile version of drag and drop
  • Refactor before adding drop restrictions
  • Adding drop restrictions

Before we will start our journey, let’s see what we will get at the end (gif):

Prerequisites

We will start from a simple React application created by using create-react-app script with few changes in a project (remove some styles and code fragments):

App component consists of two columns from/to which we will drag and drop our MovableItem:

Let’s add some not complex CSS styles, so that our examples would look not too terrible 😉:

And our application would look like this. Very simple…

Installation

To use react-dnd library we will need to add react-dnd and react-dnd-html5-backend npm packages to our project:

yarn add react-dnd react-dnd-html5-backend// ORnpm install react-dnd react-dnd-html5-backend

react-dnd-html5-backed uses the HTML5 drag and drop API under the hood.

Now we can start implementing our Drag and Drop functionality:

Implementing draggable item

Note: After code snippet screenshots, I will add gists, so you could easily copy-paste it in your code, so no worries

At first, we will need to wrap our components that are taking part in drag and drop with DndProvider.

Next, we will add useDrag hook to our “draggable” component:

Some values are irrelevant for now, like item properties, no worries, I’ll explain about them a little bit later.

Current app’s code snippet:

Wrapping component and adding useDrag hook code snippet

After updating our code, we will notice some changes in our app’s behavior → now we can drag our MovableItem (without any additional functionality).

Implementing droppable item

To make our MovableItem “droppable” to a specific region (Second component in our case) we will need to add useDrop hook, with some logic.

NOTE: I am deliberately specified accept type as Not existing type

Let’s take a look at the results:

As you can see — nothing happens. canDrop and isOver returned values only on the component’s first renders, and that’s all. Why is that?

The reason, as you might’ve guessed, is in accept type . When you got a lot of draggable objects, which you can drag from one to another — you need to specify an acceptable type, on which droppable component will react.

Let’s make it happen:

Now, let’s check it out:

Creatin kanban board

Before we will create kanban board we need to make a few changes to our code, not complex, believe me 😉.

First, we need to rename our FirstColumn and remove SecondColumn component:

Next, we will modify App component.

The reason for the refactor is that we need our MovableComponent not to be hardcoded in the FirstComponent, but to be more flexible, so that we can decide when to place it.

Now we can add some logic for moving from one column to another. It will be done by using a simple boolean variable.

Next, we can remove unnecessary logic in the “Droppable” column. All we will need is a “droppable” name (Column 1 or Column 2 in our case), which is declared at code line 41.

Next, we need to add end logic for the “droppable” item, in other words — what should be done when a user releases button after drag.

Let’s take a look at what we’ve accomplished so far:

Here is the code gist for this example.

Adding multiple draggable items

But how to handle multiple items in a column? Let’s find out.

  • Step 1: Create multiple items;
  • Step 2: Create a function that will return MovableItem that has a column name equal to our needs (Column 1 or Column 2 in our case);
  • Step 3 and 4: Add returnItemsForColumn function into Columns components

Next, we will need to modify MovableItem, so that when a user “drops” item, we could define where exactly. As you remember getDropResult() will return “droppable” object properties on which user “dropped” “draggable” item.

At Step 2 we are changing the item’s column property to the current “droppable” column name.

Let’s check it out:

I think that now you got the main idea behind the react-dnd library. But we can make it more interesting.

Make items sortable in the column

For this example, I’ve used an example by this link, but without any third-party libraries, like immutability-helper npm package, without callbacks, plus it is much interesting to add it to our app with additional functionality like columns, and check how they will work together.

At first, we will need to define a moveCardHandler, that will handle changing item position in our array.

Next, we will need to add useRef implementation instead of an old one.

Step 3 code was copied from the React DnD docs example:

Let’s take a look at what we’ve accomplished:

Mobile version of drag and drop

Note, that our previous app version will not correctly work for mobile devices:

To solve this issue we will need to add react-dnd-touch-backend npm package to our project:

yarn add react-dnd-touch-backend// ORnpm install react-dnd-touch-backend --save

After that, we will need to modify our App component:

Let’s test it:

Refactor before adding drop restrictions

I think that we can finally take a closer look at additional React DnD properties that can allow us to add some restrictions to our “draggable” and “droppable” items.

First, we will need to update some of our code fragments, so that our applications would look like this:

First, let’s create constant with Column names in a separate file:

And Tasks array with our tasks objects:

Now, we can modify our App component:

  • Step 1: Refactor old items to imported tasks;
  • Steps 2, 3, and 4: Refactor our previous code with the use of new COLUMN_NAMES;
  • Steps 5: Add new Awaiting review and Done columns.

And finally, we will need to update our previous logic for setting a new task’s column name, when a user “drops” and item to the specific column.

Gists of an App component, just in case, and updated styles.

Now, let’s check what we’ve accomplished :

As you probably guessed, we can move tasks from Do it column to Awaiting review, or Done.

Let’s add some restrictions to our kanban board.

Adding drop restrictions

After adding additional columns into our app we can add restrictions logic.

To determine to which column item currently belongs, we need to pass current column name prop to the MovableItem component:

Next, we need to add currentColumnName to the item properties in line 65, so we can get in “droppable” component:

Finally, we need to modify “droppable” component (Column component).

NOTE: defining canDrop function will override monitor.canDrop() function.

At Step 2 we are describing “if” conditions, that are defining can user drop current item onto current column or not.

Let’s take a look at what we’ve accomplished (gif):

You can check code implementation on Github or in Codesandbox:

LITSLINK Frontend Development

Your go-to place for frontend dev trends, know-hows, hacks and tricks.

Artem Diashkin

Written by

Java, Spring, Node.js, AdonisJs, React.js and Flutter developer

LITSLINK Frontend Development

Frontend development is key to user’s happiness & satisfaction. Read how Litslink’s engineering team is solving the hardest FE challenges for the most admirable startups in 2021.

Artem Diashkin

Written by

Java, Spring, Node.js, AdonisJs, React.js and Flutter developer

LITSLINK Frontend Development

Frontend development is key to user’s happiness & satisfaction. Read how Litslink’s engineering team is solving the hardest FE challenges for the most admirable startups in 2021.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store