Create Confirmation Dialog Component With ReactJS

Why a confirmation dialog?

If there is one component you will always need, whatever your application is about, it is a confirmation dialog. They are ubiquitous; whether you want to delete an entry, gather consent, or simply alert the user that a process will take some time.

In this post, I will walk through the design and development of my version of a confirmation dialog component.

It is not the only one; there are many tutorials out there covering the same subject, and you might even have a different vision of what constitutes a good confirmation dialog.

What is a confirmation dialog?

That seems like a trivial question, but the answer is crucial for designing the component properly.

A confirmation dialog is a window shown to the user when we need their confirmation to proceed with the current action. The action itself is not really relevant and can be anything. The classic use-case is deleting a record in the database.

With that definition, we can outline the main features of a confirmation dialog:

  • Display information about what the user needs to confirm.
  • A confirm button with a callback function to execute the confirmed action.
  • A cancel button that closes the dialog.

We all know how it looks, but saying — or showing in this case — the obvious is sometimes a good thing:

Example of confirmation dialog

What the component’s code looks like

Create a new file named ConfirmDialog.js.

For this component, I am using Material-UI for all the styling. However, you can use whatever you prefer; the code will not change significantly.

I will provide the code here and explain it afterward.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import * as React from 'react';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';

export default function ConfirmDialog({
title,
content,
onConfirm,
openState,
setOpenState,
cancelButtonText = "No",
confirmButtonText = "Yes",
onCancel = null
}) {

// Execute the cancel callback code and close the dialog
const handleClose = () => {
if (onCancel !== null && onCancel !== undefined) {
onCancel();
}
setOpenState(false);
};

// Execute the confirmation callback code and close the dialog
const handleConfirm = () => {
onConfirm();
setOpenState(false);
};

return (
<div>
{/* Dialog component for displaying confirmation dialog */}
<Dialog
open={openState}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
{title}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{content}
</DialogContentText>
</DialogContent>
<DialogActions>
{/* Cancel button to dismiss the dialog */}
<Button onClick={handleClose} autoFocus>{cancelButtonText}</Button>
{/* Confirm button to execute the confirmed action */}
<Button id="dialog-confirm-button" onClick={handleConfirm}>{confirmButtonText}</Button>
</DialogActions>
</Dialog>
</div>
)
}

As you can see, most of the component’s behavior is managed by the caller rather than the component itself. This might seem evident upon consideration, but as mentioned earlier, stating the obvious can still be beneficial.

While I could delve into explaining all the props here, some are relatively self-explanatory. You probably already understand the purposes of title, content, cancelButtonText, and confirmButtonText.

Here’s a brief rundown of the other props:

  • onConfirm: This prop is a callback function triggered when the confirmation button is clicked.
  • openState / setOpenState: These props consist of the open state and the corresponding state-setting function from the caller component. They are used to control the visibility of the confirmation dialog, either opening it or closing it.
  • onCancel: By default set to null, this prop offers a callback function for the cancel button click. It accommodates scenarios where more than just closing the dialog is necessary, covering those specific requirements.

Implementation

Here’s an example illustrating the usage of the component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React, {useState} from "react";
import Button from '@mui/material/Button';
import ConfirmDialog from "../components/ConfirmDialog";

function App() {
const [confirm, setConfirm] = useState(false);

function handleConfirmDialogConfirmClick() {
// Code execute when clicking on the 'Confirm' button
console.log('Confirmation');
}

function handleConfirmDialogCancelClick() {
// Code execute when clicking on the 'Cancel' button
console.log('Cancel');
}

return (
<main>
<Button onClick={(e) => setConfirm(true)}>Confirm</Button>
<ConfirmDialog
title={"Confirm?"}
content={"Do you really confirm this?"}
onConfirm={handleConfirmDialogConfirmClick}
onCancel={handleConfirmDialogCancelClick}
openState={confirm}
setOpenState={setConfirm}
/>
</main>
)
}

export default App;

Now you can test it out and determine if this approach suits your needs.

Conclusion (kind of)

That is a straightforward component, and there are opportunities for enhancements. For instance, currently, pressing the ‘Escape’ key on your keyboard will close the confirmation dialog, but pressing ‘Enter’ doesn’t have any effect.

Furthermore, the UI/UX could be enhanced further. You have the option to incorporate animations or customize the CSS for a more polished appearance.

If you’ve read through this entire post, I appreciate your attention, and I hope you found this information valuable.