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.
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:
Bashnpm 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:
JSXimport { 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
- Refactor your list: Wrap your existing list items in the
@dnd-kitSortableContext. - State Management: Ensure your component state updates locally immediately upon
onDragEndto keep the UI snappy, then fire theupdateOrderAPI call in the background. - Visual Feedback: Add a CSS class to the item being dragged (using the
isDraggingstate provided byuseSortable) to change its opacity or shadow.
Common Pitfalls
- Z-Index Issues: Ensure that the element being dragged has a higher
z-indexthan the surrounding container, or it will appear to "slide under" other items. - Missing Keys: React requires unique
keyprops 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.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard โ by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds โ familiar editing, modern speed.