React drag and drop

temitope emmanuel
The Andela Way
Published in
3 min readAug 9, 2018
Photo by Clément H on Unsplash

So recently, I found myself working on a project that required me to implement a drag and drop feature. With no prior knowledge on how this works, first thing I did was to google things out, try to get context on how drag and drop even works.

I found out HTML5 already has this property, which made life easier but only if I was just building a webpage with no framework like React. I was able to walk my way through implementing it.

Moving forward, HTML5 has four properties to make drag and drop work; draggable, ondragstart, ondragover and ondrop.

Draggable, when added as an attribute to a HTML element, makes the target element to become draggable.

ondragstart, is called immediately the element dragged. Usually the content to be dragged about is set at this point.

ondragover, is added as an event listener to the element where the dragged content will be dropped. In other words, it is used to specify where the content is to be dropped.

ondrop, is called immediately the dragged content is released on the element that contains the ondragover event listener.

More details and explanation on these can be found here.

With all these known, implementing in react isn’t difficult as it might have sounded in the beginning right? 😉. So to implement this feature in react, we will be building a simple task manager like Trello 😎.

So for starters, we have our code block in the app.css and app.jsx file below

So in the above code snippets, we have an array of todos, empty array of completedTasks in our state, and an empty object initialised in our state. Also, we have two main children divs (todos and done) contained in the parent div with className App. While the upper snippet contains the css.

The idea of this simple app is to move elements from the todos array to the completedTasks array and display the changes (which is what react does anyway 🤓).

First step is to make each child element of the todos div draggable by adding the draggable attribute onDrag event listener to the element like in the example below;

<div className="todos"> {   todos.map(todo =>    <div     key={todo.taskID}     draggable     onDrag={(event) => this.onDrag(event, todo)}
>
{todo.task} </div>) }</div>

The draggable as said earlier enables the element which added to, to be dragged as needed while the onDrag as an event listener, calls the onDrag method when fired.

onDrag = (event, todo) => {  event.preventDefault();  this.setState({    draggedTask: todo  });}

Above, the onDrag method takes in the event object and the dragged todo as parameters whenever it is called and stores the todo in the component’s state as draggedTask.

Next, we make the done div look like this;

<div  onDrop={event => this.onDrop(event)}  onDragOver={(event => this.onDragOver(event))}  className="done">
...
</div>

Following this, the following methods will be added to our component

onDragOver = (event) => {  event.preventDefault();}onDrop = (event ) => {  const { completedTasks, draggedTask, todos } = this.state;  this.setState({    completedTasks: [...completedTasks, draggedTask],    todos: todos.filter(task => task.taskID !== draggedTask.taskID),    draggedTask: {},  });}

With this, when the item is released or dropped on the target done div, the onDrop method is fired courtesy of the event listener added earlier.

What this method simply does is get the previously stored task in the state, add it to the list of completedTasks, filters the todos list to remove this item as it has been moved and then assigns the initially set draggedTask to an empty object.

NB: All these are done in the called setState method.

Thank you for reading. Link to the full code can be found here.

Do you need to hire top developers? Talk to Andela to help you scale.
Are you looking to accelerate your career as a developer? Andela is currently hiring senior developers.
Apply now.

--

--