Learn to build a safe, user-centric Modal confirmation system in your WordPress React admin UI to prevent accidental data loss during API operations.
Previously in this course, we explored handling conflict resolution to maintain data integrity during concurrent edits. In this lesson, we shift our focus to user-side safety: we will implement a robust Modal system to ensure users explicitly confirm destructive actions before we trigger any API requests.
In a professional plugin, "Delete" buttons are dangerous. If a user accidentally clicks a button that triggers an immediate DELETE request, they lose data instantly. To provide a high-quality UX (User Experience), we must introduce a Confirmation step that interrupts the flow, forces the user to pause, and requires a deliberate action to proceed.
A modal should be a controlled component in React. Rather than embedding the modal logic directly inside your list items, you should lift the state to your parent component or a dedicated UI manager.
You need two pieces of state:
isOpen: A boolean to track visibility.targetId: The ID of the item currently marked for deletion (so we know what to delete once confirmed).We will leverage @wordpress/components to keep our UI consistent with the WordPress admin design system. Specifically, the Modal component handles the overlay and the focus trapping for us.
JSXimport { Modal, Button } from CE9178">'@wordpress/components'; import { useState } from CE9178">'@wordpress/element'; const DeleteConfirmationModal = ({ isOpen, onClose, onConfirm, itemName }) => { if (!isOpen) return null; return ( <Modal title="Confirm Deletion" onRequestClose={onClose} isDismissible={true} > <p>Are you sure you want to delete "{itemName}"? This action cannot be undone.</p> <div style={{ display: CE9178">'flex', justifyContent: CE9178">'flex-end', gap: CE9178">'10px' }}> <Button variant="tertiary" onClick={onClose}>Cancel</Button> <Button variant="primary" isDestructive onClick={onConfirm}>Delete Permanently</Button> </div> </Modal> ); };
To integrate this into our Knowledge Base plugin, we need to connect the UI button click to the modal, and the modal confirmation to our existing service layer.
If you have already mastered implementing CRUD in the admin UI, you know that the delete function is likely an asynchronous call. Here is how we bridge the two:
JSXconst KnowledgeBaseList = () => { const [isModalOpen, setIsModalOpen] = useState(false); const [itemToDelete, setItemToDelete] = useState(null); const handleDeleteClick = (item) => { setItemToDelete(item); setIsModalOpen(true); }; const confirmDeletion = async () => { await deleteKnowledgeBaseItem(itemToDelete.id); // From your service layer setIsModalOpen(false); setItemToDelete(null); // Trigger UI refresh here }; return ( <> {/* List items with buttons */} <Button onClick={() => handleDeleteClick(item)}>Delete</Button> <DeleteConfirmationModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} onConfirm={confirmDeletion} itemName={itemToDelete?.title} /> </> ); };
DeleteConfirmationModal component to your project.itemToDelete state when the delete button is clicked.onConfirm callback resets the modal state and invokes your API service.Modal is closed properly when the user presses Esc or clicks the backdrop. WordPress components handle this, but if you build a custom overlay, you must manage onKeyDown listeners manually.z-index of your admin container. WordPress uses specific layers for its own UI; try to render your modal at the root level using a React Portal if necessary.itemToDelete state after the API promise resolves.We have moved beyond basic CRUD by adding a safety layer. By implementing a state-driven Modal for Confirmation, we prevent accidental data loss and provide a professional interface for your users. This pattern is essential for any plugin handling content modification.
Up next: We will implement comprehensive activity logging to track these deletions and other changes in our custom database tables.
Learn to build robust input validation for your WordPress plugin. Discover how to provide instant client-side feedback and handle server-side errors gracefully.
Read moreLearn to build a robust audit system by hooking into the WordPress REST API, logging changes to a custom table, and displaying the history in your React UI.
Building a Modal Confirmation System
Handling Large Datasets with GraphQL
Implementing Real-time Updates with Web