Learn How To Create A Drag And Drop Component In React Native

June 28, 2021 Publish By : EXPERT APP DEVS 7 min read Viewed By : 947
Drag And Drop Component In React Native

In this article, I am going to explain you how to create a drag-and-drop component and its use cases. To understand how drag-and-drop works, we’ll create a  react native application, so let’s start…

Drag and Drop in React Native

What is drag and drop component - 

Drag and drop are draggable components in react native, which you can drag any other place where you want.

This API is a most integral part of modern apps, it enhances the UX.

Most use cases-

Here we are talking about some of the most usable cases in our applications.

  • Implement drag and drop when you upload the image or files from the gallery.
  • Moving the items in any list such as - trello or any other app like this.
  • You can use this for rearranging the images etc.

You can find many more other examples in apps which you use regularly.

Options for creating drag and drop -

There are so many options for creating drag and drop functionality in react native, if we want to create it custom then we need these 2 - react native component

  • PanResponder
  • Animated
  • Dimensions

Or we can use a third party library as well, which is 

  • React-dropzone

Creating drag and drop using panResponder-

In this section we can create the drag and drop option using panResponder and animation.

First we need to import the PanResponder class, then create a .create method in 

componentWillMount() life cycle method. We can also use 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

  }

});

  • First we need to initialize the panResponder and creates a reference for it, which is created by

this.panResponder = PanResponder.create()

  • Now we are going to utilize this reference in our <Animate.View> 
  • We use it by {…this.panResponder.panHandlers} here we use it passing by props.

Call it and return it - 

Here we call the function for returning the design view.

componentWillMount() {

  ...

    this.panResponder = PanResponder.create({

      ...

      onPanResponderRelease: (e, gesture) => {

        Animated.spring(this.state.pan, {

          toValue: { x: 0, y: 0 },

          friction: 5

        }).start();

      }

    });

  Now you get the value of the draggable component.

Creating a area for dropping - 

Here we create the area for where we drag and drop the creating view.

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"

 }

});

Now we need to add the logic for the dragging element.

 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;

  }

So this one is completed, I think you find it a good read.

Need a consultation?

Drop us a line! We are here to answer your questions 24/7.