Skip to content

Commit

Permalink
docs(blog): update React-DND article with performance optimization te… (
Browse files Browse the repository at this point in the history
  • Loading branch information
necatiozmen authored Dec 25, 2024
1 parent 159aa53 commit 60622de
Showing 1 changed file with 112 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ description: We'll be using the react-dnd library to create draggable components
slug: react-draggable-components-with-react-dnd
authors: david_omotayo
tags: [react, Refine, tutorial]
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-03-07-react-dnd/social.png
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-03-07-react-dnd/social-2.png
hide_table_of_contents: false
---

**This article was last updated on December 24, 2024, to include advanced techniques for optimizing React-DND performance, such as avoiding unnecessary re-renders, virtualizing large lists, and supporting mobile devices with the Touch Backend, along with simplified explanations for better clarity.**

<br/>

<img src="https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-03-07-react-dnd/final-min.gif" alt="react draggable" />

<br />

# Introduction
## Introduction

The HTML Drag-and-Drop API is a pioneering feature of the web, whose introduction has inspired developers to find innovative ways of using it to enhance the user experience on their websites.

Expand Down Expand Up @@ -688,15 +690,6 @@ Now, if you save your project go back to the browser, you should see the cards r
<img src="https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-03-07-react-dnd/rendering-cards.png" alt="react draggable" />
<br />
<br/>
<div>
<a href="https://discord.gg/refine">
<img src="https://refine.ams3.cdn.digitaloceanspaces.com/website/static/img/discord_big_blue.png" alt="discord banner" />
</a>
</div>
## Using the useDrag hook
To make our cards draggable, we'll declare the `useDrag` hook inside the `cards` component, give it a `type` and item `value`, and then pass the `dragRef` variable to the card component using the `ref` attribute.
Expand Down Expand Up @@ -901,6 +894,114 @@ If you save your progress and revisit the browser, you should now be able to dra
That's all. We have successfully created a kanban board with draggable cards and columns with drop zones. You can enhance the appearance by adding designs based on the state of each card and column.
## Optimizing Performance with React-DND
Performance can become an issue when working with React-DND, especially with a large number of draggable items. Below are some tips to keep things running efficiently:
**Avoid Unnecessary Re-Renders**
Utilize `React.memo` or `useMemo` to avoid unnecessary re-renders. For instance, if your draggable items remain unchanged, memoizing them can save a lot of processing time.
**Batch State Updates**
When updating multiple items after a drop, batch those updates instead of triggering multiple state changes. This minimizes React’s render cycles.
**Minimize the `collect` Function’s Scope**
The `collect` function in `useDrag` and `useDrop` is powerful, but adding excessive logic can degrade performance. Only gather data that’s absolutely necessary.
**Virtualize Large Lists**
For hundreds of draggable items, consider using libraries like `react-window` or `react-virtualized`. These libraries render only the visible items, reducing React’s workload.
By applying these strategies, you’ll achieve a drag-and-drop experience that is both fast and functional.
## Error Handling and Debugging
React-DND is a robust library, but you might encounter some common issues. Here’s how to resolve them:
**Missing `DndProvider`**
If you forget to wrap your app with `DndProvider`, nothing will work. Ensure your root component includes it:
```jsx
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";

function App() {
return (
<DndProvider backend={HTML5Backend}>
<YourApp />
</DndProvider>
);
}
```
**Type Mismatches Between useDrag and useDrop**
The type property in useDrag must match the accept property in useDrop. Otherwise, the drop zone won’t recognize the dragged item:
```tsx
const [{ isDragging }, dragRef] = useDrag({ type: "item" });
const [{ isOver }, dropRef] = useDrop({ accept: "item" });
```
**Monitor Data Not Updating**
If collect isn’t providing accurate data, ensure you’re returning the correct values from the monitor:
```tsx
collect: (monitor) => ({ isDragging: monitor.isDragging() });
```
Debugging these small issues can save significant time. Always refer to the documentation and browser console for detailed error messages.
**Mobile Device Support**
React-DND’s default backend (HTML5Backend) works well on desktop browsers but struggles on mobile devices. Here’s how to enable drag-and-drop for touchscreens:
**Use the Touch Backend**
Install the react-dnd-touch-backend package designed for touch devices:
```
npm install react-dnd-touch-backend
```
**Set Up the Touch Backend**
Replace HTML5Backend with TouchBackend in your app’s DndProvider:
```tsx
import { DndProvider } from "react-dnd";
import { TouchBackend } from "react-dnd-touch-backend";

function App() {
return (
<DndProvider backend={TouchBackend}>
<YourApp />
</DndProvider>
);
}
```
**Customize Touch Behavior**
You can tweak the touch backend’s settings for better performance, such as adjusting the drag delay:
```tsx
const backendOptions = {
enableMouseEvents: true,
delay: 100,
};

<DndProvider backend={TouchBackend} options={backendOptions}>
<YourApp />
</DndProvider>;
```
With these adjustments, your drag-and-drop features will work seamlessly across both desktop and mobile devices.
## Conclusion
This article introduced Refine and React-DND, detailing the process of setting up a Refine project with predefined CRUD pages via the Superplate CLI and integrating React-DND. It also covered the creation of a dashboard page featuring a kanban board that utilizes the useDrag and useDrop hooks from React-DND for its drag-and-drop functionality.
Expand Down

0 comments on commit 60622de

Please sign in to comment.