Back to Blog
Lesson 35 of the Intermediate WordPress Plugins: REST API & React Admin course
WordPressJune 26, 20263 min read

Implementing Drag-and-Drop Sorting in WordPress React Plugins

Learn how to implement drag-and-drop sorting in your WordPress React admin dashboard using @dnd-kit to improve UI/UX for your Knowledge Base plugin.

WordPressReactUI/UXDrag and dropREST APIJavaScriptphpplugin-development

Previously in this course, we covered Implementing CRUD in the Admin UI: WordPress REST API & React, where we built the foundational logic for managing items. In this lesson, we take that foundation further by implementing an intuitive drag-and-drop interface, allowing users to reorder items visually.

Understanding Drag and Drop in React

In a WordPress admin context, UI/UX is paramount. Users expect modern, interactive interfaces. When dealing with a list of Knowledge Base entries, a simple "order" input field is clunky. Drag-and-drop provides immediate visual feedback.

We will use @dnd-kit, a modern, modular library that handles the complexities of pointer events, collision detection, and accessible keyboard interactions. It is significantly lighter and more flexible than older libraries like react-beautiful-dnd.

Implementing the Drag-and-Drop Interface

First, install the necessary dependencies:

Bash
npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities

To implement sorting, we need a wrapper around our list items that provides the sorting context. Here is a simplified implementation for a SortableList component:

JSX
import { DndContext, closestCenter } from CE9178">'@dnd-kit/core';
import { arrayMove, SortableContext, verticalListSortingStrategy } from CE9178">'@dnd-kit/sortable';
import { SortableItem } from CE9178">'./SortableItem'; // Your custom item component

export const KnowledgeBaseList = ({ items, onReorder }) => {
    const handleDragEnd = (event) => {
        const { active, over } = event;

        if (active.id !== over.id) {
            const oldIndex = items.findIndex(i => i.id === active.id);
            const newIndex = items.findIndex(i => i.id === over.id);
            const newOrder = arrayMove(items, oldIndex, newIndex);
            
            // Sync with WordPress via API
            onReorder(newOrder);
        }
    };

    return (
        <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
            <SortableContext items={items} strategy={verticalListSortingStrategy}>
                {items.map(item => <SortableItem key={item.id} id={item.id} title={item.title} />)}
            </SortableContext>
        </DndContext>
    );
};

Handling Order Updates via REST API

When the drag operation completes, we must persist the new order to the database. Since we previously learned about Implementing Nonce Verification for WordPress REST API Security, ensure your apiFetch call includes the correct security headers.

Create a function in your service layer to handle the batch update:

JAVASCRIPT
// services/kb-service.js
export const updateOrder = async (items) => {
    return apiFetch({
        path: CE9178">'/kb/v1/reorder',
        method: CE9178">'POST',
        data: {
            items: items.map((item, index) => ({ id: item.id, order: index }))
        }
    });
};

In your PHP endpoint, you will loop through the items array and update the menu_order property of each post using wp_update_post.

Hands-on Exercise

  1. Refactor your list: Wrap your existing list items in the @dnd-kit SortableContext.
  2. State Management: Ensure your component state updates locally immediately upon onDragEnd to keep the UI snappy, then fire the updateOrder API call in the background.
  3. Visual Feedback: Add a CSS class to the item being dragged (using the isDragging state provided by useSortable) to change its opacity or shadow.

Common Pitfalls

  • Z-Index Issues: Ensure that the element being dragged has a higher z-index than the surrounding container, or it will appear to "slide under" other items.
  • Missing Keys: React requires unique key props for list items. If you use the index as a key during sorting, React will struggle to track the DOM elements correctly, causing the drag-and-drop animation to glitch. Always use the database ID.
  • Over-fetching: Don't trigger a full page re-render from the server after a reorder. Update the local state using the new array, and let the API response silently confirm the persistence.

Recap

We have successfully integrated dnd-kit to transform a static list into an interactive, sortable interface. By combining local state optimization with persistent API updates, we've created a professional-grade admin experience for our Knowledge Base plugin.

Up next: We will consolidate our API logic by Creating Custom Hooks for API Logic, which will clean up our component code and make our data fetching easier to maintain.

Similar Posts