Drag and Drop in React with React DnD
Tags: react, tutorial, javascript
Published: 2022-01-14 18:39:51

Drag and drop is a common feature that many websites you interact with may have. While there are ways to do this with vanilla javascript, html, and css, it doesn't have to be that hard with React DnD. Here we will go through a super simple example of how to implement drag and drop functionality.

### Getting Started
Once you have your react application set up, you will want to install React DnD as well as the backend which takes care of all the HTML drag and drop functionality behind the scenes.
```
npm install react-dnd react-dnd-html5-backend
```
### Importing and Initializing SetUp
Now that we have React DnD in our project packages, we will want to wrap the main component that is being rendered with a DndProvider. Be sure to import DndProvider and the Backend from the packages you just installed. Our HTML5Backend will be passed as a prop to the DndProvider component.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vm01pl1jy7db0oq2miio.png)
Next we will take a look at that Dragdrop component, which will render the interface for our drag and drop example.

### Containers and Items
The goal of this tutorial will be to drag images from one container to populate an initially empty drop board. We will start with an array of objects that will store our image urls attached to an id number. This will become important a little bit later when specifying what image we want to drop into our drop board.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1z87bcc6u93ql5tk1n22.png)
Then to render our pictures, we will map over our list and send each individual picture to a separate Picture component. All the picture components we accumulate will be added to the initial box that images can be dragged from.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6p140u5ijsvnyhqnh2v.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ebhys8w3x8qo9f579rq.png)

Now we'll take a look at our Picture component which is taking in the url and id as props from our list of images.

### Draggable Component
We want our pictures to be draggable, so this is where we will use the useDrag hook from React DnD.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qhb9i71d7uckmgef20d.png)
Notice how useDrag is being initialized, with the object _isDragging_, and a ref _drag_. The useDrag hook is initialized with an object containing keys type, item, and collect. The type can be named arbitrarily, but we will soon see that our Drop hook will have to take the same type so it can receive the correct item. Our item will use the picture id so our app knows which picture has been selected to drag. Finally, React DnD looks for our user's action through monitor to determine if an item is currently being dragged or not. This response information is associated with the collect key.

Our final return for the Picture component will take in the _drag_ ref and _isDragging_ boolean so we can make some stylistic changes when the user is dragging an item.

### Dropping Items
Now that we can drag items, we need to have a place to drop them. Back in our Dragdrop component, we can use a state variable to hold an array of all the items we are dropping into the drop board. Then similarly to the useDrag hook, we will now use the useDrop hook to take our item and add it to our drop board.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/so9g1lwj8yuhlux9xcec.png)
Alternatively to drag, _isOver_ and _drop_ will now be used to see if the item is being held over a valid place to drop. The useDrop hook will look to accept the type that was specified in our draggable component. When the item is dropped over a valid section, the item will be added to the board state, filtering from the original list of pictures by the id that we gave the item. And again, to determine if the user is holding the item over a valid place to drop, the monitor will look to see if it is over a corresponding container.

Once we have the new updated board in state, we can render the picture again but this time in the new drop board. To make a new container where we can drop items, we need to add the _drop_ ref. To visualize, we can again use _isOver_ to change some styling about our drop container.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kl3l021k8fp3g8e74ie.png) 

### Final Product
Now with a bit of styling to our components we can see the following when dragging one of the images over the drop board.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xznj117m56fegiy80chu.png)
Once it is dropped, the board will have our new picture!
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8s279nfkt1j18nmdfeqp.png)

These are the css styles I used for this simple example:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34bku46cebckz2v3bot3.png)
 
I would highly recommend taking a look at the official React DnD documentation where they give even further capabilities to this library.
https://react-dnd.github.io/react-dnd/about

If you're interested in the code used for this tutorial you can find the full repository here:
https://github.com/jyeett/dragdrop