Setting up react-beautiful-dnd in your React application

Aviral Jain
4 min readMar 11, 2023

--

react-beautiful-dnd is a React library to apply beautiful and accessible drag and drop for list elements.

Installation

  • Open terminal with your project directory and install
    react-beautiful-dnd
# yarn
$ yarn add react-beautiful-dnd

# npm
$ npm install react-beautiful-dnd

Setting up in Project

  • For this tutorial, I’ll be applying react-beautiful-dnd in a simple note taking react project like below:
An image consisting of note components on which drag drop is to be applied.
  • The above page is rendered with the following component:
import useFetch from "../config/useFetch";
import NoteCard from "../components/NoteCard";

const Home = () => {
const { notes, setNotes, fetchError } = useFetch();

return (
<div className="page">
{fetchError && <h2>{fetchError}</h2>}
{notes && (
<div className="notes">
<div className="notes-grid">
{notes.length === 0 ? (
<div className="empty">
<h1>No Notes Yet</h1>
</div>
) : (
notes.map((note, index) => (
<NoteCard note={note} index={index} />
)
)}
</div>
</div>
)}
</div>
);
};

export default Home;
  • Start with importing DragDropContext, Draggable and Droppable from react-beautiful-dnd in your component file where you want to apply drag and drop facility in your react project.
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'
  • Visual representation how these three components work is given below:
  • Use the <DragDropContext> tag to enclose the div containing all note elements (the area where all drag and drops are intended to occur).
  • Now use the <Droppable> tag inside the <DragDropContext> and use a JavaScript function with an argument of provided which returns the same div containing the note elements.
  • Give the props {…provided.droppableProps} and
    ref={provided.innerRef} to the top level div which is inside the function.
  • Before closing the top level div tag which is inside function, add a value {provided.placeholder} at the end.
  • Also make sure to provide a droppableId to the Droppable component.
    In my case, my droppableId is notes.
import useFetch from "../config/useFetch";
import NoteCard from "../components/NoteCard";
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';

const Home = () => {
const { notes, setNotes, fetchError } = useFetch();

return (
<div className="page">
{fetchError && <h2>{fetchError}</h2>}
{notes && (
<div className="notes">
<DragDropContext>

<Droppable droppableId="notes">
{(provided) => (
<div
className="notes-grid"
{...provided.droppableProps}
ref={provided.innerRef}
>
{notes.length === 0 ? (
<div className="empty">
<h1>No Notes Yet</h1>
</div>
) : (
notes.map((note, index) => (
<NoteCard note={note} index={index} />
))
)}

{provided.placeholder}
</div>
)}
</Droppable>

</DragDropContext>
</div>
)}
</div>
);
};

export default Home;
  • Now we’ll use the <Draggable> tag to wrap our each div which is going to be draggable. In my case I’ll wrap my <NoteCard> component inside map function as my every note is to be dragged and dropped.
  • Inside <Draggable> tag open a JavaScript function with argument provided and return the component that is supposed to be dragged.
notes.map((note, index) => (

<Draggable key={note.id} draggableId={note.id?.toString()} index={index}>
{(provided) => (
<div
{...provided.dragHandleProps}
{...provided.draggableProps}
ref={provided.innerRef}
>
<NoteCard note={note} index={index} />
</div>
)}
</Draggable>

))
  • Because I’m using a component inside the <Draggable> tag, the draggable tag’s props cannot be used in it. We’ll need a parent div to wrap our <NoteCard> component and serve as our top level div.
  • We will then pass our draggable props {…provided.dragHandleProps},
    {…provided.draggableProps} and ref={provided.innerRef} in our top level div tag. Also give a unique draggableId to <Draggable> tag.
  • You should now be able to drag and drop components in your project, but after dropping the component, its state does not change and it returns to its original position.

Managing the state on drag and drop

  • To manage the state of components when dropping them, we have to create a function which will save the new order of the mapped array.
  • We’ll create a function handleOnDragEnd which have an argument result and this function will be passed in <DragDropContext> as a prop.
...
<DragDropContext onDragEnd={ handleOnDragEnd }>
...
  • The result argument is the object that shows some data about the component which is dragged and dropped and also includes its source index and destination index.

You can try logging it out in console for better understanding

const handleOnDragEnd = (result) => {
if(!result.destination){
return
}

const items = Array.from(notes);
const [reorderedNotes] = items.splice(result.source?.index, 1);
items.splice(result.destination?.index, 0, reorderedNotes);

setNotes(items);
}
  • The handleOnDragEnd function above gets the source index of the dragged item and puts it in the destination index and finally updates the state.
  • If we try to drop the item outside the droppable area, then the destination index will be null and function will simply return.
  • Our final code snippet would be as follows:
  • Now our home page would look like this:

Conclusion

That’s how you can setup react-beautiful-dnd in your React application.

--

--

Aviral Jain

Hi, I'm Aviral , a computer science engineering student and full-stack developer. My expertise lies in Java, React, JavaScript, TypeScript, Spring and more.