Persist List Reordering with react-beautiful-dnd using the onDragEnd Callback

Alex Reardon
InstructorAlex Reardon
Share this video with your friends

Social Share Links

Send Tweet

In this lesson will demonstrate how you can persist changes locally that resulted from a drag and drop interaction.

To accomplish this, you will implement the onDragEnd callback function that is invoked at the end of every react-beautiful-dnd drag and drop. This function receives a result object. We will use the source and destination properties of the result object to update the order of our task list

Instructor: [00:02] We can now drag things around in our task list application. There are interactions are not being persisted, and a task list is reverting to its original state after drop animation completes. We'll now work on persisting needs changes in a onDragEnd function.

[00:20] Firstly, what's this result object? What information have we been given? Here is an example, result object. A result has a draggable ID. This is the ID of the draggable that the user was dragging. It has a type property, which will go into in a live lesson, and the reason for the drop. This could be drop or cancel.

[00:40] Generally, it's not super important to know whether the user dropped explicitly or cancel the drags say by using the escape key, but you do have our information, if you needed. We now have two really important objects, the source and destination.

[00:55] These objects contain location information about where the draggable started and where it finished. In this case, the draggable started in column 1 in index 0and finished in the same column, column 1 in index 1. There are cases where the destination can be null, such as where the user drops outside of a list.

[01:23] Then, you grab the information that we are interested in from the result object. If there's no destination, then there's nothing that we need to do as a result of this drag, so we can simply exit.

[01:43] A little check that I like to add is to see if the location of the draggable changed. We do that by checking to see if the destination droppable ID is the same as the source, and if the index has the same in the destination as the source. If these two things are true, then the user drop the item back into the position that is started, so we don't need to do anything.

[02:06] At this point, we need to reorder the task IDs array for the column. We'll stop by retrieving our column from the state. I've used the ID of the droppable from the source object to look up the column from my state.

[02:30] However, I could have also just I miss, because I know that I only have one column in this system, but this feels a little bit more robust. If I was to change the ID of the column in my initial data, then I would need to update this. Look up here.

[02:53] This will create a new task IDs array with the same contents as our last array. When I do update, I generally try to avoid mutating my existing state, and rather creating new objects for the things that I change.

[03:09] We now need to move the task ID from its old index to its new index in the array. What splice will do? Is it actually modifying the array, or it will modify new task IDs? Saying from this index we want to remove one item.

[03:40] We're also going to use splice again. This time we're going to start from the destination index. We're going to remove nothing. I'm going to insert the draggable ID, which we know is the task ID. There's lots of different ways of ordering an array. This is just one of them.

[04:04] I'm now going to create a new column, which has the same properties as our old column over the new task IDs array. Now that we have our new column, we're going to put that into a new picture of our state.

[04:27] I'm using object spread to maintain the old properties in our state object, but also invalidating the references of the past that I want to change.

[04:35] I'm now going to insert the new column into this map. This will override our existing column. Technically, right now, we don't need this spread, because we only have one column, but I think this is good practice to do. When I'm going to call this.setState, which will update the state for our React component...Come back to our task list application, we can now say that our reorder operations are being preserved.

[05:14] We have optimistically updated our UI without waiting for several confirmation. How you persist this change to your data store, will depend on your state management solution and server architecture.

[05:25] A simple strategy for persisting changes would be to call an end point, after performing this optimistic update to let your server know that a reorder has occurred.