Introduction
Mobile swiping is a common gesture that allows users to interact with content in a fluid and intuitive way. You can use mobile swiping to create features such as carousels, sliders, or cards that can be swiped left or right to reveal more information or actions.
In this blog post, I will show you how to build a mobile swiping component in React using the react-swipeable
library. This library provides a custom hook that enables you to handle swipe events and gestures in your React components. You will learn how to:
- Install and use the
react-swipeable
library - Create a simple swiping component with React
- Add custom logic and styles to the swiping component
Install and use the react-swipeable
library
The react-swipeable
library is a lightweight and easy-to-use library that allows you to add swipe functionality to your React components. You can install the library using npm or yarn:
npm install --save react-swipeable
To use the library, you need to import the useSwipeable
hook from the library and pass it an object with your swipe handlers. The hook returns an object with the handlers
property, which you can spread onto the element that you want to make swipeable. For example:
import { useSwipeable } from 'react-swipeable';
function App() {
// Define the swipe handlers
const handlers = useSwipeable({
onSwipedLeft: () => console.log('Swiped left!'),
onSwipedRight: () => console.log('Swiped right!'),
onSwipedUp: () => console.log('Swiped up!'),
onSwipedDown: () => console.log('Swiped down!'),
});
// Return a swipeable element
return <div {...handlers}>You can swipe here</div>;
}
The useSwipeable
hook accepts an object with the following properties:
onSwiped
: A function that is called when a swipe is completed in any direction. It receives an event object with the swipe data, such as the direction, distance, velocity, etc.onSwipedLeft
,onSwipedRight
,onSwipedUp
,onSwipedDown
: Functions that are called when a swipe is completed in a specific direction. They receive the same event object asonSwiped
.onSwiping
: A function that is called when a swipe is in progress in any direction. It receives the same event object asonSwiped
.onSwipingLeft
,onSwipingRight
,onSwipingUp
,onSwipingDown
: Functions that are called when a swipe is in progress in a specific direction. They receive the same event object asonSwiped
.delta
: A number that defines the minimum distance in pixels that the user must swipe before the swipe is recognized. The default value is10
.preventDefaultTouchmoveEvent
: A boolean that determines whether to prevent the default touchmove event when swiping. The default value isfalse
.trackMouse
: A boolean that determines whether to track mouse events as well as touch events. The default value isfalse
.trackTouch
: A boolean that determines whether to track touch events. The default value istrue
.rotationAngle
: A number that defines the rotation angle in degrees of the element that is swipeable. The default value is0
.
Create a simple swiping component with React
To create a simple swiping component with React, you can use the useState
and useEffect
hooks to manage the state and the side effects of the component. You can also use the useSwipeable
hook to handle the swipe events and gestures.
For example, suppose you want to create a component that displays a list of items that can be swiped left or right to reveal some actions. You can use the following code to create the component:
import React, { useState, useEffect } from 'react';
import { useSwipeable } from 'react-swipeable';
function SwipeList({ items }) {
// Define the initial state
const [activeIndex, setActiveIndex] = useState(0);
const [swipeDir, setSwipeDir] = useState(null);
// Define the swipe handlers
const handlers = useSwipeable({
onSwipedLeft: () => setSwipeDir('left'),
onSwipedRight: () => setSwipeDir('right'),
preventDefaultTouchmoveEvent: true,
trackMouse: true,
});
// Define the effect to update the active index based on the swipe direction
useEffect(() => {
if (swipeDir === 'left') {
setActiveIndex((prevIndex) =>
prevIndex < items.length - 1 ? prevIndex + 1 : prevIndex
);
} else if (swipeDir === 'right') {
setActiveIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex));
}
// Reset the swipe direction after updating the index
setSwipeDir(null);
}, [swipeDir, items.length]);
// Return the swipeable list
return (
<div className="swipe-list" {...handlers}>
{items.map((item, index) => (
<div
key={index}
className={`swipe-item ${index === activeIndex ? 'active' : ''}`}
>
<div className="swipe-content">{item.content}</div>
<div className="swipe-actions">
<button className="swipe-action swipe-action-left">
{item.actionLeft}
</button>
<button className="swipe-action swipe-action-right">
{item.actionRight}
</button>
</div>
</div>
))}
</div>
);
}
This code does the following:
- It defines a
SwipeList
component that receives an array ofitems
as a prop. Each item is an object that has the following properties:content
,actionLeft
, andactionRight
. - It defines the initial state using the
useState
hook. The state consists of two variables:activeIndex
, which is the index of the currently active item, andswipeDir
, which is the direction of the last swipe. - It defines the swipe handlers using the
useSwipeable
hook. It sets thepreventDefaultTouchmoveEvent
andtrackMouse
options totrue
, to prevent scrolling and enable mouse events. It also sets theswipeDir
state variable toleft
orright
when a swipe is completed in either direction. - It defines the effect using the
useEffect
hook. The effect runs whenever theswipeDir
or theitems.length
changes. It updates theactiveIndex
state variable based on theswipeDir
value, using thesetActiveIndex
function. It also resets theswipeDir
value tonull
after updating the index. - It returns the swipeable list using the
handlers
object from theuseSwipeable
hook. It maps over theitems
array and renders aswipe-item
element for each item. It also adds aswipe-content
element that displays the item’s content, and aswipe-actions
element that displays the item’s actions. It also adds aactive
class to theswipe-item
element that matches theactiveIndex
value.
Add custom logic and styles to the swiping component
To add custom logic and styles to the swiping component, you can use the onSwiping
and onSwiped
handlers from the useSwipeable
hook to access the swipe data and manipulate the component’s appearance and behavior. You can also use CSS transitions and transforms to create smooth and realistic animations for the swiping component.
For example, suppose you want to add the following features to the swiping component:
- Show the left or right action button when the user swipes the item in either direction, and hide the button when the user releases the item.
- Apply a rotation and a scale effect to the item when the user swipes the item, and reset the effect when the user releases the item.
- Trigger the left or right action function when the user swipes the item beyond a certain threshold, and reset the item’s position and appearance.
You can use the following code to add these features to the component:
// Import React and the useSwipeable hook
import React, { useState, useEffect } from 'react';
import { useSwipeable } from 'react-swipeable';
// Define the SwipeList component
function SwipeList({ items }) {
// Define the initial state
const [activeIndex, setActiveIndex] = useState(0);
const [swipeDir, setSwipeDir] = useState(null);
const [swipePos, setSwipePos] = useState(0);
const [swipeStyle, setSwipeStyle] = useState({});
// Define the swipe handlers
const handlers = useSwipeable({
// Set the swipe direction state when a swipe is completed
onSwipedLeft: () => setSwipeDir('left'),
onSwipedRight: () => setSwipeDir('right'),
// Update the swipe position and style state when a swipe is in progress
onSwiping: (eventData) => {
// Get the swipe distance and direction
const { dir, deltaX } = eventData;
// Set the swipe position state
setSwipePos(deltaX);
// Set the swipe style state
setSwipeStyle({
// Apply a rotation and a scale effect based on the swipe direction and distance
transform: `rotate(${deltaX / 10}deg) scale(${1 - Math.abs(deltaX) / 1000})`,
});
},
// Prevent the default touchmove event and enable mouse events
preventDefaultTouchmoveEvent: true,
trackMouse: true,
});
// Define the effect to update the active index based on the swipe direction
useEffect(() => {
// Check the swipe direction
if (swipeDir === 'left') {
// Increment the active index if it is not the last item
setActiveIndex((prevIndex) =>
prevIndex < items.length - 1 ? prevIndex + 1 : prevIndex
);
} else if (swipeDir === 'right') {
// Decrement the active index if it is not the first item
setActiveIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex));
}
// Reset the swipe direction after updating the index
setSwipeDir(null);
}, [swipeDir, items.length]);
// Define the effect to trigger the action function based on the swipe position
useEffect(() => {
// Define the threshold for triggering the action
const threshold = 300;
// Get the current item and its action functions
const item = items[activeIndex];
const { actionLeft, actionRight } = item;
// Check if the swipe position exceeds the threshold
if (swipePos < -threshold && actionLeft) {
// Trigger the left action function
actionLeft();
// Reset the swipe position and style
setSwipePos(0);
setSwipeStyle({});
} else if (swipePos > threshold && actionRight) {
// Trigger the right action function
actionRight();
// Reset the swipe position and style
setSwipePos(0);
setSwipeStyle({});
}
}, [swipePos, items, activeIndex]);
// Return the swipeable list
return (
<div className="swipe-list" {...handlers}>
{items.map((item, index) => (
<div
key={index}
className={`swipe-item ${index === activeIndex ? 'active' : ''}`}
style={index === activeIndex ? swipeStyle : {}}
>
<div className="swipe-content">{item.content}</div>
<div className="swipe-actions">
<button className="swipe-action swipe-action-left">
{item.actionLeft}
</button>
<button className="swipe-action swipe-action-right">
{item.actionRight}
</button>
</div>
</div>
))}
</div>
);
}
This code does the following:
- It styles the
swipe-list
element to fill the entire screen and hide the overflow. - It styles the
swipe-item
element to have a fixed width and height, and center it horizontally and vertically. It also adds a transition effect to the transform property, which creates a smooth animation for the swipe. - It styles the
swipe-content
element to have a white background and a black border, and show some text and an image. - It styles the
swipe-actions
element to have a transparent background and a white text, and position it on the left and right edges of the swipe content. - It styles the
swipe-action
elements to have a fixed width and height, and remove the default border and outline.
Conclusion
In this blog post, I have shown you how to build a mobile swiping component in React using the react-swipeable
library. You have learned how to:
- Install and use the
react-swipeable
library - Create a simple swiping component with React
- Add custom logic and styles to the swiping component
Mobile swiping is a great way to create interactive and engaging web applications. With the react-swipeable
library, you can easily add swipe functionality to your React components and customize them to suit your needs.
I hope this blog post has helped you to understand how to build a mobile swiping component in React. If you want to learn more about the react-swipeable
library, you can check out the following resources:
Happy swiping! 😊