Create a Drag and Drop Component in React Native (2024)

Create a Drag and Drop Component in React Native (1)

While brainstorming my next React Native app, here’s my first, I wanted to see if there’s an API that tracks gesture so I could create a drag and drop component.

Luckily, it wasn’t too hard to find: we have the PanResponder! With this we can track gesture as an abstracted state and update our UI accordingly.

What we will be build

Create a Drag and Drop Component in React Native (4)

Creating a Draggable Component

I found the documentation for PanResponder API is a bit hard to follow, but this example and animation guide helped get me going

After importing PanResponder class, you initiate it with .create method in componentWillMount() life cycle method. You could also write it in the constructor() .

import React, { Component } from "react";
import {
StyleSheet,
View,
PanResponder,
Animated
} from "react-native";

export default class Draggable extends Component {

constructor() {
super();
this.state = {
pan: new Animated.ValueXY()
};
}

componentWillMount() {

// Add a listener for the delta value change
this._val = { x:0, y:0 }
this.state.pan.addListener((value) => this._val = value);
// Initialize PanResponder with move handling
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, gesture) => true,
onPanResponderMove: Animated.event([
null, { dx: this.state.pan.x, dy: this.state.pan.y }
])
// adjusting delta value
this.state.pan.setValue({ x:0, y:0})
});
}

render() {
const panStyle = {
transform: this.state.pan.getTranslateTransform()
}
return (
<Animated.View
{...this.panResponder.panHandlers}
style={[panStyle, styles.circle]}
/>
);
}
}

let CIRCLE_RADIUS = 30;
let styles = StyleSheet.create({
circle: {
backgroundColor: "skyblue",
width: CIRCLE_RADIUS * 2,
height: CIRCLE_RADIUS * 2,
borderRadius: CIRCLE_RADIUS
}
});

this.panResponder = PanResponder.create() initiates the panResponder and creates a reference. We utilize it in our <Animate.View> component by passing{…this.panResponder.panHandlers} like we’re passing a group of props.

Inside thePanResponder.create() we set onStartShouldSetPanResponder to true so the panResponder will respond to touch feedback. Then we pass an Animated.event to onPanResponderMove: to update the location of our Animated.View circle component that the user is gesturing with.

To get our circle’s position we get the calculated animated value from this.state.pan.getTranslateTransform() and use it to create a transform style that we pass to our Animated.View.

Finally, we adjust delta value so the element won’t jump on the second touch.

At this point we have a draggable circle that the user can interact with:

Create a Drag and Drop Component in React Native (5)

Returning the Circle to its Initial Location

We want the circle to return to its original location when they release the component. To do this we use onPanResponderRelease to tell the UI how to respond when the user lets go.

componentWillMount() {
...
this.panResponder = PanResponder.create({
...
onPanResponderRelease: (e, gesture) => {
Animated.spring(this.state.pan, {
toValue: { x: 0, y: 0 },
friction: 5
}).start();
}
});

Our circle now returns to its initial location:

Create a Drag and Drop Component in React Native (6)

Creating the Drop Area

Now that we have the drag, we need the drop. We create another component with our drop area and use our Draggable component within it:

import React, { Component } from "react";
import { StyleSheet, View, Text } from "react-native";
import Draggable from "./Draggable";

export default class Screen extends Component {
render() {
return (
<View style={styles.mainContainer}>
<View style={styles.dropZone}>
<Text style={styles.text}>Drop them here!</Text>
</View>
<View style={styles.ballContainer} />
<View style={styles.row}>
<Draggable />
<Draggable />
<Draggable />
<Draggable />
<Draggable />
</View>
</View>
);
}
}

const styles = StyleSheet.create({
mainContainer: {
flex: 1
},
ballContainer: {
height:200
},
row: {
flexDirection: "row"
},
dropZone: {
height: 200,
backgroundColor: "#00334d"
},
text: {
marginTop: 25,
marginLeft: 5,
marginRight: 5,
textAlign: "center",
color: "#fff",
fontSize: 25,
fontWeight: "bold"
}
});

Then we add a bit of logic to Draggable, its onPanResponderRelease handler, and add a function to determine if we’re in the drop area. Note: We make assumptions about the drop zone’s location on the screen here.

...
constructor()
super.props();
this.state = {
showDraggable: true,
dropAreaValues: null,
pan: new Animated.ValueXY(),
opacity: new Animated.Value(1)
};
}
componentWillMount() {
...
this.panResponder = PanResponder.create({
...
onPanResponderRelease: (e, gesture) => {
if (this.isDropArea(gesture)) {
Animated.timing(this.state.opacity, {
toValue: 0,
duration: 1000
}).start(() =>
this.setState({
showDraggable: false
})
);
} else {
Animated.spring(this.state.pan, {
toValue: { x: 0, y: 0 },
friction: 5
}).start();
}
}
isDropArea(gesture) {
return gesture.moveY < 200;
}

And that’s it. Our Screen should now look like this:

Create a Drag and Drop Component in React Native (7)

To see the source code and play with the live demo check out the Expo Snack I created for this demo.

Conclusion

The PanResponder API was a bit intimidating for me at first, but now I think this is a great API that anyone can use to make the user experience in their apps better.

I hope this article has helped you out, reach out in the comments with questions or concerns. Thanks for reading, and happy coding!

*Korean version of this article hasn’t written yet.

Create a Drag and Drop Component in React Native (2024)
Top Articles
Medical Causes of Excessive Sleepiness
Yellow Jackets | Bloomingdale, IL
Great Clips Mount Airy Nc
Foxy Roxxie Coomer
Diario Las Americas Rentas Hialeah
123 Movies Black Adam
Best Transmission Service Margate
Umn Pay Calendar
Craigslist Phoenix Cars By Owner Only
Rls Elizabeth Nj
Ohiohealth Esource Employee Login
Camstreams Download
Lima Crime Stoppers
Synq3 Reviews
Connexus Outage Map
Nj Scratch Off Remaining Prizes
Dirt Removal in Burnet, TX ~ Instant Upfront Pricing
Inter-Tech IM-2 Expander/SAMA IM01 Pro
Hollywood Bowl Section H
Best Mechanics Near You - Brake Masters Auto Repair Shops
We Discovered the Best Snow Cone Makers for Carnival-Worthy Desserts
Fsga Golf
Mc Donald's Bruck - Fast-Food-Restaurant
The EyeDoctors Optometrists, 1835 NW Topeka Blvd, Topeka, KS 66608, US - MapQuest
Purdue 247 Football
Boston Dynamics’ new humanoid moves like no robot you’ve ever seen
Rubber Ducks Akron Score
Cain Toyota Vehicles
Crossword Help - Find Missing Letters & Solve Clues
Silky Jet Water Flosser
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Jcp Meevo Com
15 Primewire Alternatives for Viewing Free Streams (2024)
The Fabelmans Showtimes Near Baton Rouge
Weather Underground Durham
CohhCarnage - Twitch Streamer Profile & Bio - TopTwitchStreamers
Worthington Industries Red Jacket
Uno Fall 2023 Calendar
Davita Salary
Ravens 24X7 Forum
A Grade Ahead Reviews the Book vs. The Movie: Cloudy with a Chance of Meatballs - A Grade Ahead Blog
Jambus - Definition, Beispiele, Merkmale, Wirkung
Nsu Occupational Therapy Prerequisites
Robot or human?
Craigslist Hamilton Al
Acadis Portal Missouri
Raisya Crow on LinkedIn: Breckie Hill Shower Video viral Cucumber Leaks VIDEO Click to watch full…
Ursula Creed Datasheet
Alston – Travel guide at Wikivoyage
Yale College Confidential 2027
Menu Forest Lake – The Grillium Restaurant
Guidance | GreenStar™ 3 2630 Display
Latest Posts
Article information

Author: Roderick King

Last Updated:

Views: 6225

Rating: 4 / 5 (51 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Roderick King

Birthday: 1997-10-09

Address: 3782 Madge Knoll, East Dudley, MA 63913

Phone: +2521695290067

Job: Customer Sales Coordinator

Hobby: Gunsmithing, Embroidery, Parkour, Kitesurfing, Rock climbing, Sand art, Beekeeping

Introduction: My name is Roderick King, I am a cute, splendid, excited, perfect, gentle, funny, vivacious person who loves writing and wants to share my knowledge and understanding with you.