A Swipeable and Sortable List in React Native

Justin Rohweller
6 min readApr 11, 2018

--

Edit: I recently published a barebones npm module that essentially does this tutorial and a bit more. See https://github.com/JustinRohweller/react-native-sort-and-swipe-list . Don’t have much time to work on this, but viewing the example in there should help anyone who wants to make a sortable and swipeable list.

I have been using react native for about two years now and I believe it is an excellent language that still has several uncharted territories. I am writing this simple, tutorial-like article in order to show how I explored one of these territories: making a sortable and swipeable list. I faced this issue while making my app, Todays Todos, which you can find on both google play and the ios app store.

Let’s get to it. This would work without Expo, but I think it is an excellent tool that is easy to use, and so it’s being used in this scenario. Make a new blank project.

Create a new project.

Go to react native sortable list on github by typing react-native-sortable-list into the interwebs.

Find example on the page. Click on Basic.

You should be somewhere that looks like this. Copy everything from App.js, put it in your App.js (using whatever editor you like).

Then, open up whatever console you use (for me it is PowerShell), and type npm install — save react-native-sortable-list react-native-swipe-list-view. This will install the two libraries that we need. Next, you can try testing the app. You should see exactly the same example as on the react-native-sortable-list github.

Next, Find SortableList in your code, and add the prop: manuallyActivateRows. This allows the whatever component is in the renderRow to use a function called toggleRowActive, which will act as though the user picked up or dropped a list item.

Add the SwipeRow import at the top of your file from swipe list view.

Import TouchableOpacity from react native.

Find the row style at the bottom of the file. Change the width to be window.width minus 30 * 2 instead of 20 for both android and ios.

Add a touchable opacity surrounding everything inside the Animated.View, along with onLongPress={this.props.toggleRowActive}. Here you can retest your application if you would like, as it should still work as a sortable list, although to sort you will need to press on the text or image.

Copy paste entire row style (the one we changed earlier) into touchable opacity for an inline style. Then, comment out all styles that have the word margin, and finally, decrease width by 40 instead of 30. I generally discourage inline styles that are this big, but for a tutorial and for clarity I think it is fine.

Now your list should really be a sortable list that feels almost identical to the first sortable list render from example, with a few small issues (we’ll get to these later.

Now to swiping. Use basically same dimensions for a swipeRow, that will surround the entire animated.view.(slightly bigger so that it will envelop the whole thing). I put rightOpenValue for -100 and leftOpenValue for 60 so you can easily see the row open and close, however, these can obviously be whatever you like.

For the swipeRow to work, however, it needs something to render behind each row. So, we place an empty view behind.

That’s it. A swipeable and sortable list in react native!

Issues:

There will be an issue with items not being dropped after being picked up and not moved, and unfortunately the solution requires messing with the library sortable list.

Essentially, one needs to know if the row has moved, which will be in onPanResponderMove inside the react-native-sortable-list library. If row has been long pressed, and has not been moved, and has been dropped, call toggleRowActive. This requires adding some sort of prop in sortable list that tells us whether a row has moved (bubbles up from onPanResponderMove). Since this tampers with the library, I did not put it in my tutorial. Let me know if there are different solutions.

There will be another issue with open rows being left open when other rows are opened, which also can be solved by tampering with a library, in this case, react-native-swipe-list-view. Solution: Use swipegesturebegan (not in the docs for swiperow, but awesome that they have it) and refs to each row to check if a row is starting to be opened, if one is, close all other rows. In order to close all other rows, however, you need to have a ref list of all the swiperows, so that you can call a function inside the swiperow component called closeRow(), or manuallySwipeRow(0) (these both do the same thing).

There are probably better solutions to both of those problems, but that is what I did.

Onwards:

Feel free to change the style of each item any way you like, you just have to modify the swiperow, hiddenrow, animated view, and the touchableopacity style each time. I recommend using one style for all, and override it a bit for each of these. Add some buttons behind your item, and you’re good to go.

What should change with these libraries to improve: fix the previously mentioned two issues, or even add a new combined library. First issue: just add allow the row component in sortable list to access a rowHasMoved function or sortSwipeBegan or something. Second issue: just add swipeGestureBegan in docs for swipeRow, add shouldRowClose or even a function which simply closes the row if any other PanResponder takes control of the screen, which could be a boolean prop.

I hope this tutorial helped someone, I know it would have helped me, and if there is anyone out there trying to make a sortable and swipeable list with react native, then here is one possible solution. If you want to check out an app in action, Todays ToDos does exactly this method.

TLDR; To make a swipeable and sortable list, import react native sortable list and react native swipe list view, and wrap your row in renderRow with SwipeRow.

This is my first article, so if you like it, feel free to let me know what you think in the comments.

--

--

Justin Rohweller
Justin Rohweller

Written by Justin Rohweller

I'm a freelance React Native developer that rarely writes articles. I enjoy videogames, soccer, and all the things.

Responses (3)