Drag and Drop in React with ‘react-sortable-hoc’
We have all been used to dragging and dropping items on websites for years. Since it is such a common behavior on websites, I figured as a web developer, I should be able to do it. After a quick search, I had a plethora of react libraries to choose from. I ended up settling on one called ‘react-sortable-hoc.’ The major difference between this library and some of the more popular ones that I saw is that this one allows you to move items horizontally and vertically in a grid. The other ones that I saw mostly restrict you to moving items vertically or horizontally within their container. It is pretty simple to add to any React app, and today I will show you how.
First, we have to make sure to install all of the dependencies that we are going to need. So, we have to run ‘npm install react-sortable-hoc,’ and then ‘npm install array-move.’ Now, we can get to the code.
It is important to note that ‘react-sortable-hoc’ requires that your components follow some structural rules. You must use two components from the package; ‘SortableContainer,’ and ‘SortableItem.’ The names do a pretty good job of illustrating their purposes. In the example I built, the 3x3 grid is the container, and the squares with Pokemon images on them are the items. I chose to build those as functional components, with the Pokemon data being passed down as props from ‘App.js.’ We also need our SortableContainer to have a function called ‘onSortEnd’ as a prop. This function tells our app what the new order of our Pokemon should be. It can be copy and pasted from the ‘react-sortable-hoc’ docs, just make sure you change ‘items’ to the name of the piece of state you are passing down as props. Now that we are on the topic, make sure you are passing down a piece of state, and not just an array or object. Since ‘onSortEnd’ uses ‘setState’, it will not work if you try to sort anything outside of state. We must also make sure to import ‘arrayMove’ from ‘array-move’ because our ‘onSortEnd’ method calls it.
The component ‘PokeList’ is our 3x3 grid. I passed down the ‘onSortEnd’, the array of Pokemon data, and specified the axes of movement I want to allow. The axis prop is part of ‘react-sortable-hoc,’ and you can choose between ‘x,’ ‘y,’ or ‘xy.’ These determine whether the items can move horizontally, vertically, or both.
Since the PokeList is going to be our SortableContainer, we have to make sure to import SortableContainer and wrap our component in it, as seen above. This component is our grid, and is tasked with rendering each of our Pokemon within it. So, here we are mapping the array of all the Pokemon data that was passed down as a prop into new components that we have called PokeTiles. As you may have noticed, we are passing index as an argument to ‘.map.’ This is because we have to assign each of our PokeTiles an index prop, otherwise our ‘onSortEnd’ method in App.js will not know where in the array our Pokemon are being moved.
Above is the PokeTile component. Similar to the PokeList, we have to wrap it with something from ‘react-sortable-hoc.’ This time, it is SortableElement. We set it to display the image that we passed down, and we are good to go!
This is much easier to set up than I would have expected beforehand. However, make sure that you are following the general pattern of wrapping the area you want to be draggable in a SortableContainer, and the items themselves in SortableItem. Do not forget to add the index, or to keep the items you are moving around within state. I hit those errors myself, so that you don’t have to :).
Thanks for reading!