Building a Swipeable List with React

In this tutorial, you will learn how to create a react list component where each element can be swiped to trigger an action.

A typical example of this is "swipe to delete" used in many android applications.

We will discover, how we can build such a list using nothing but react itself.

Also, you will learn, how to add smooth animations to make the list feel even more natural to use.

Ad the end you will have a generic component, that can be used across all of your projects:

Ready?

Let's get started!

Setting up a new React project

Before we get started, we need to set up a new react project. To do we will create the create-react-app-tool.

To create a new project, open a new terminal window and type:

npx create-react-app swipeable-list

Because this project has no dependencies other than react, that is all that we need to do.

Creating a swipeable list component

Let's start by creating the swipeable list component. To do that, go ahead and create a directory called SwipeableList inside of the src directory. This is to keep our component nice and tidy in one folder.

Afterward, create two new files called SwipeableList.js and SwipeableList.css inside of the SwipeableList directory.

The SwipeableList component will not have any functionality other than to wrap the SwipeableListItem components we are going to create later. This wrapper would allow us to add some styling to the overall list, e.g. apply padding.

So all we do is rendering the components' children inside of a wrapper-div with the class "List".

The layout

Next, we are going to take a look at the layout of our component.

The component has two layers. A foreground, which will contain the content of the list item and can be swiped from right to the left, and a background, that appears in a different color and has some text to it.

Again, the SwipeableListItem does not contain the content itself. Instead, it expects it to be passed via its children (this.props.children). That way, we keep the component reusable, because any content can be projected inside of the container.

For example:

<SwipeableListItem><h1>Hello World</h1></SwipeableListItem>

Adding element references

To be able to manipulate the different layers and implement the swipe functionality later, we need a direct reference to the DOM element.

When the user is touching the list item, we keep track of where exactly he started dragging by setting the "dragStartX" variable. Also we set the "dragged" variable to true. We then update the variable "left" every time the cursor (or the finger) moves.

Here is what that looks like in more detail:

onDragStart

When the user starts dragging the item, we need to react to that by setting "dragStartX" and "dragged" accordingly.

To do so, we define two methods. One for the mouse event and one for the touch event. We need to do so because their API is slightly different. If you don't care about mouse support, feel free to drop that part.

Both of these methods calling a general method called onDragStart. This is where the shared logic is placed. Afterward, both methods add an event listener for the move event.

Inside of the onDragStart method, we adjust our properties. Then, we use the requestAnimationFrame function to request a callback. Inside of this callback, we will take care of the style adjustments that need to happen to move the foreground to the position of the cursor.

onTouchMove

When the user is touching the list item, we are registering new event listeners to the "touchmove" and "mousemove" events. Now we need to react to these position changes by adjusting the "left" variable accordingly.

We do so by subtracting the value of dragStartX, which is the offset of the cursor to the top-left of the list item, from the position of the cursor. Without the offset, the top-left corner would always jump to the position of the cursor. We don't want that.

In this example, the threshold can be controlled via a property called "threshold". If that property is not provided, a fallback value of 0.3 is used. This means that the list item has to be moved around a third of its width to the left to trigger the delete event.

In that case, the property "onSwipe" is called if possible. That is done using the "onSwipe" method:

src/SwipeableList/SwipeableListItem.js

onSwiped() {if (this.props.onSwipe) {this.props.onSwipe(); } }

The required event listeners for this are added when the component mounts

Stay up to date about what is going on in the web-dev community and on this site.

Special offers

Get notified about special offers of our own, or our partners' products. Don't worry, we won't spam your inbox!

Your Email Address

Yes, I want to subscribe to the email newsletter about new articles, products and special offers.

You can change your mind at any time by clicking the unsubscribe link in the footer of any email you
receive from us. For more information about our privacy practices, email performance mesurements, logging of the registration
process and your rights, please take a look at our
Privacy Policy

Join the Newsletter

Never miss a post

Receive updates when a new post is published.

Stay in touch

Stay up to date about what is going on in the web-dev community and on this site.

Special offers

Get notified about special offers of our own, or our partners' products. Don't worry, we won't spam your inbox!

Your Email Address

Yes, I want to subscribe to the email newsletter about new articles, products and special offers.

You can change your mind at any time by clicking the unsubscribe link in the footer of any email you
receive from us. For more information about our privacy practices, email performance mesurements, logging of the registration
process and your rights, please take a look at our
Privacy Policy