Hi there, my name is Fupeng Wang.
I am a senior full-stack engineer, and author of a 17.5k open-source project, PMP. Now I am developing a Notion-style knowledge base
HuashuiAI including AI writing and collaboration, using React Nextjs and Supabase.
In this article, I will share how to implement tree-list drag and drop sortable by React and dnd-kit. The source code link is at the bottom of this article.
Dnd-kit and Sortable component
Dnd-kit is a common drag-drop tool in the React ecosystem, and it supports sortable by default.
<dndcontext sensors="{sensors}" collisiondetection="{closestCenter}" ondragend="{handleDragEnd}"> <sortablecontext items="{items}" strategy="{verticalListSortingStrategy}"> {items.map(id => <sortableitem key="{id}"> <p>But it can only support the one-level list. If we want to implement a multi-level nested list (or tree), we have to customize it.</p> <h2> Define state date structure </h2> <p>Modern front-end frameworks such as React Vue are data-driven views, so defining data structures first and then considering UI rendering.</p> <p>The most common data structure definition for multi-level nested lists (trees) is as follows, and virtual DOM vnode is also defined in this way.<br> </p> <pre class="brush:php;toolbar:false">const defaultItems = [ { id: 'A', children: [] }, { id: 'B', children: [ { id: 'B1', children: [] }, { id: 'B2', children: [ { id: 'B2a', children: [] }, { id: 'B2b', children: [] }, ], }, ], }, { id: 'C', children: [] }, { id: 'D', children: [ { id: 'D1', children: [] }, { id: 'D2', children: [] }, ], }, { id: 'E', children: [] }, ]
Multi-level nested SortableContext is not feasible
Because the state data structure is nested, the first thing that comes to my mind is to nest and render the UI structure together.
Firstly, nest
Then, continue nesting the subordinate
The running effect is as follows. The problem is that drag and drop sorting is allowed within the same level, but cross level sorting is not possible because it is not a context - which is reasonable
Multi level conversion to a single level is feasible
Since nesting is not feasible, it is necessary to convert multiple levels into the single level.
But it is necessary to add the ancestorsIds attribute for each item, firstly to display the depth of the hierarchy, and secondly to know what parent nodes it has.
interface IItem { id: string ancestorIds?: string[] children?: IItem[] } function flatten(items: IItem[]): IItem[] { return items.reduce<iitem>((acc, item) => { acc.push(item) if (item.children) { const children = item.children.map((i) => ({ ...i, ancestorIds: [...(item.ancestorIds || []), item.id], // add ancestorIds })) acc.push(...flatten(children)) } return acc }, []) } </iitem>
The rendering effect after conversion is as follows, and you can now drag and sort it. However, it will not take effect until the state sorting is modified.
In addition, we can also determine whether it can be moved through the hierarchical relationship of ancestorsIDs. The parent node cannot be moved to its child nodes, otherwise the loop will be dead.
For example, in the above figure, if we want to drag B2 to the position of B2a, we will find that the ancestorsIDs of B2a contain B2. This is not possible because you cannot drag an item to its own subordinate.
Modify state data
For ease of operation, the data is placed in the Zustand global store.
Dnd-kit refers to the dragged element as an activeItem and the placed target location as an overItem. So modifying state data means moving activeItem to the position of overItem.
If it is a single level, Dnd-kit provides a method arrayMove that can be directly modified. The doc link https://docs.dndkit.com/presets/sortable
But in multi-level nested lists (trees), you need to implement it yourself, which is a bit troublesome. The core code is here, and you can download the source code (at the end of the article) for reference.
Encountered a problem
As shown in the figure below, when dragging A under B, A will move to the bottom of B as a whole, not inside B.
To solve this problem, it is necessary to determine whether there are any child elements of B after B. If so, assign overItem to its child elements
Then insert the current active element into the first element of items.
The end
The source code link is here https://github.com/wangfupeng1988/react-dnd-sortable-demo
By the way, I am looking for an international job opportunity, if you have a chance, welcome to connect me on my Github profile.
The above is the detailed content of React dnd-kit, implement tree-list drag and drop sortable. For more information, please follow other related articles on the PHP Chinese website!

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SublimeText3 Chinese version
Chinese version, very easy to use

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
