Introducing Autopilot, an AI coding assistant
gradient
How to use the React Draggable component

How to use the React Draggable component

Priya Patel
Growth Associate
Jun 14, 2023
11 min read

Drag-and-drop functionality is an important component of modern UX design. Users may use this functionality for things like reordering items in a list, moving objects in a graphics editor, drag-and-drop file loading, or grouping different elements together. Drag-and-drop functionality is built into HTML in the form of the Drag and Drop API, but the API is notoriously quirky and difficult to work with, so many have developed libraries to help handle dragging and dropping without making the developer interact with the HTML Drag and Drop API directly.

In this article, we'll introduce a draggable component library called React Draggable, and discuss how to use these React Draggable components.

What is React Draggable?

There are several different libraries that help create "draggable" React components. One of them is react-draggable.

React Draggable is a simple, customizable library that creates draggable components that manage their own state. It works by wrapping the React component in a <Draggable> component. Users can control various behaviors using certain predefined props. For example, users can set the axis prop to allow for movement only on the x or the y axis or set the bounds prop to force the draggable component to stay within a certain area.

The react-draggable library is useful when users want to quickly implement a draggable UI element in React but do not want to interact with the HTML Drag and Drop API. While React Draggable isn't as flexible as React DnD, it's easy to understand and use for simpler use cases.

Implementing a draggable list app using React Draggable

In this article, we'll walk through how to make a list app with draggable notecards using React Draggable. You can view the GitHub repo for this project to follow along.

Creating the app and installing React Draggable

Let's start by creating the app and installing React Draggable. In this example, we will be using Create React App. To create the app using Create React App, type the following in the console:

bash

This creates a React app called draggable-list, then changes directories into that folder.

Next, install React Draggable using npm, and start the server:

bash

Creating the components and connecting them

In the src folder, create another folder called components. In the components folder, create two files: Card.jsx and List.jsx. <Card> components will be draggable "index cards" with a header that can be edited and a text box where notes can be written. The <List> component will serve as a container for the <Card> components. For now, add placeholder code to each file.

In Card.jsx, type the following:

javascript

This creates a simple <Card> component with a header area and an area for written content. For now, enter placeholder text in those <div>s.

Next, in List.jsx, type the following:

javascript

Here, we are importing the new <Card> component and returning a <div> with a single <Card>. We will be adding more cards later, but for now, we want to make sure everything is importing and rendering correctly.

Finally, remove the section of code in the App.js file that's inside the outermost <div> and replace it with one <List> component. Don't forget to import the <List> component from the components folder:

javascript

Adding some styles

We can add some CSS styles to make it easier to see the components. Delete the contents of App.css, then add styles for the list, card, header, and content classes. Use the following styles:

scss

If we use the above styles, the app will look something like this:

Displaying cards in the list

Now, we'll use React's useState hook to create a state variable to store some cards.

First, import the useState hook from React, then use a destructured array to create a state variable. For now, we'll be creating cards using dummy data for the card titles. Eventually, we'll create functionality to add new cards with custom titles.

In List.jsx, add the following before the return statement:

javascript

This creates the variable cards that stores the current state and a function setCards that updates that state and initializes it to a short array of dummy card objects.

Then, in place of the single <Card> component, use the map method to map the elements of the cards array to <Card> components, as follows:

javascript

This creates a <Card> component for every object in the cards array, passing the object's title and id as props to that <Card> component.

After implementing this, we can check the app in the browser, and it should look something like this:

Notice that although we passed card.title to the <Card> components as a prop, this is not reflected in the cards themselves. This is because the contents of Card.jsx are still hard-coded.

To display the cards' titles, change Card.jsx to the following:

javascript

Don't forget to pass the props parameter to the <Card> component.

Now, the header should display the title prop:

Before working on the content portion of the <Card> component, we can make the cards draggable.

Making the cards draggable

Although the cards are created, they're not draggable by default. Adding this function is very straightforward using react-draggable.

In Card.jsx, first import the <Draggable> component as we see here:

javascript

Then, wrap the outermost <div> in a <Draggable> component. The <Card> component should now look like this:

javascript

Check out the app again; we should now be able to drag and drop the cards anywhere on the page.

Dealing with the strict mode error

We can now drag and drop your cards, but if we view the console, we'll see the following warning:

We got this warning because React Draggable uses the deprecated React method findDOMNode, and Create React App uses strict mode by default. As it says in the error message, we can fix this by adding a ref directly to the referenced element.

To do this, edit Card.jsx as follows:

javascript

Reload the page and check the console again. The warning should now be gone.

Creating a function to add cards

Now, we can add some more interactivity to the app by creating the capability to add new cards. To do this, we'll create a form in the UI to add a new card and a state variable to store that new card. Then, we'll create a function that takes the contents of that variable and adds it to the existing list of cards.

First, add a simple form to List.jsx. The form contains a text box where the user can type a name for a new card, along with a button to add the new card:

xml

To improve the form's appearance, we can add some more styles in App.css:

scss

This form has no functionality yet, but we'll hook it up so that typing in the text box sets the new card variable, and pushing the button adds that new card to the list.

In the <List> component, create a new state variable to store the contents of the text field as the user types before they're added to the cards array as a new card:

javascript

As you can see in the above code, the initial value of newCard is just an empty string.

Next, in the <List> component, create a function that updates the cards array to include this new card. This function will be called when the "New Card" button is pressed. It will take the contents of the newCard variable to add to the end of the cards array:

javascript

This function uses the spread operator to create a copy of the cards array and stores it in a temporary variable called tempArr. It then creates a new card object using the value of newCard (which will be a title chosen by the user) and an ID. Then, it pushes that card object to the temporary array, sets cards to that array, and clears the value of newCard.

Finally, we need to connect the form so that when the user types in the text field and presses the "Add Card" button, their card is added to the cards array. This change in the array will trigger a re-render and add their new card to the UI. To do this, make the following additions to the form in List.jsx:

javascript

This code sets the value of the text field as the value of the newCard variable. As the user types, that value is changed using the setNewCard function. Then, when the button is clicked, the addCard function is called.

We can now add new cards and drag them around to reorder them.

Making the cards editable

Next, we'll make the text within the draggable cards editable. To achieve this, let's use conditional rendering to show a text box when the user is editing and show a <p> element containing what they typed. We'll use the useState hook again to store text typed by the user.

To do this, let's make a few changes to Card.jsx.

First, import useState from React. Since we already wrote code to import useRef, the edit will look like the following:

javascript

Next, create two state variables using useState:

javascript

The first variable will store the text entered by the user and allow us to set that text. The second stores a Boolean value that represents whether the user is currently editing the text.

Next, let's make it so that the user can click the <p> element on the card to edit the text. After editing, they can click on a "Save" button to save the text.

To accomplish this, in the <div> with the content class, replace the placeholder text with the following:

javascript

This code uses a ternary operator to check to see if isEditing is set to true. If it is, it returns a <div> containing a <textarea> that, when typed in, sets the value of text to what the user types. Double-clicking clears the current text.

There's also a button inside this <div> that sets isEditing to false when clicked, indicating that the user is done changing the text.

If isEditing is false, a paragraph is displayed containing the value of the text variable. Clicking this paragraph sets isEditing to true again.

We can also add styles to the <textarea> element by adding the following to App.css:

scss

Here's a new editable card in action:

Giving the cards a handle

Now that clicking a section of the card indicates that the user wants to edit the text, it might make sense to add a "handle" to drag the card. This will help prevent the user from accidentally triggering the editing function. Luckily, adding this feature is easy with React Draggable.

Simply change the <Draggable> component to look like this:

javascript

This code makes it so the user can only drag the card by clicking the <div> element with the class name header:

And that's how to use React Draggable components. Although React Draggable components are easy to visualize and move around, they can be challenging to customize and are more suited for simple use cases.

If you're looking to build and customize complex UIs easily, then Airplane is a better solution for you.

Airplane: an easy way to build and customize UIs

Airplane is the developer platform for building custom internal tools. Airplane Tasks are single or multi-step operations that anyone on your team can use. Airplane Views allows users to build complex UIs within minutes using code.

Airplane supports an extensive component and template library out-of-the-box that makes it simple for users to get started. Engineers can also utilize third-party components or easily create their own components in Airplane.

If you're interested in building your first Airplane UI using out-of-the-box components within minutes, sign up for a free account or book a demo.

If you are at a startup that is series A or earlier with under 100 employees, check out our Airplane Startup Program for $10,000 in Airplane credits for a year.


Author: Veronica Stork

Veronica Stork is a technical writer with hands-on experience in software engineering. She is passionate about creating clear documentation and tutorials that make complicated concepts easy to understand.

Share this article:
Priya Patel
Growth Associate
Priya is currently a Growth Associate at Airplane. Before that, she was a Strategy Manager at Salesforce.

Subscribe to new blog posts from Airplane.