react-confirm is a lightweight library that simplifies the implementation of confirmation dialogs in React applications by offering a Promise-based API that works seamlessly with async/await syntax, similar to window.confirm
.
One key feature of react-confirm is that it doesn't provide a specific view or component for the confirmation dialog, allowing you to easily customize the appearance of the dialog to match your application's design.
React is a powerful library that allows for reactive rendering based on component state. However, managing temporary states like confirmation dialogs can quickly become complex. The question is: is it worth implementing these states within your app? The answer is not always a clear yes.
react-confirm library offers several benefits:
react-confirm
version 0.2.x or 0.3.xreact-confirm
version 0.1.xconfirmable
HOC to your component (Optional. See confirmable
implementation).createConfirmation
by passing your confirmable
component.confirmable
HOC to your component.import * as React from 'react';
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/Button'
import { confirmable, ConfirmDialog } from 'react-confirm';
export interface Props {
confirmation?: string;
};
const Confirmation: ConfirmDialog<Props, boolean> = ({show, proceed, confirmation}) => (
<Dialog onHide={() => proceed(false)} show={show}>
{confirmation}
<button onClick={() => proceed(false)}>CANCEL</button>
<button onClick={() => proceed(true)}>OK</button>
</Dialog>
);
export default confirmable(Confirmation);
createConfirmation
import { createConfirmation } from 'react-confirm';
import YourDialog from './YourDialog';
// create confirm function
export const confirm = createConfirmation(YourDialog);
Now, you can show dialog just like window.confirm with async-await. The most common example is onclick handler for submit buttons.
import { confirmWrapper, confirm } from './confirm'
const handleOnClick = async () => {
if (await confirm({
confirmation: 'Are you sure?'
})) {
console.log('yes');
} else {
console.log('no');
}
}
You can check more complex example in codesandbox
By default, this library renders the confirmation dialog without appending the component to your app's React component tree. While this can be useful, it may cause issues if you need to consume context in your component. To overcome this problem, you can use the MountPoint
component to include your confirmation dialog within your app's tree, enabling it to access context and other data from the app.
Create your own createConfirmation
function and MountPoint
Component using createConfirmationCreater
and createReactTreeMounter
.
import { createConfirmationCreater, createReactTreeMounter, createMountPoint } from 'react-confirm';
const mounter = createReactTreeMounter();
export const createConfirmation = createConfirmationCreater(mounter);
export const MountPoint = createMountPoint(mounter);
Put MountPoint
into your React tree.
const YourRootComponent = () => {
return (
<YourContext.Provider>
<MountPoint />
<YourApp />
</YourContext.Provider>
)
}
use your createConfirmation
as usual.
export const confirm = createConfirmation(YourDialog);
To render the confirmation dialog within the React component tree but in a different part of the DOM, you can pass a DOM element to the createReactTreeMounter
function. This will use the createPortal
method to render the confirmation dialog in the specified DOM element while keeping it within the React component tree.
const mounter = createReactTreeMounter(document.body);
Context example with Chakra-ui in codesandbox
Below, we present two possible ways to define a confirmation dialog component using react-confirm. You can choose either based on your preference.
const Confirmation1: React.FC<ConfirmDialogProps<Props, Response>> = (props) => (<Dialog></Dialog>)
const Confirmation2: ConfirmDialog<Props, Response> = (props) => (<Dialog></Dialog>)
When defining your dialog component, set both the Props
for the dialog and the Response
value to be passed when the dialog closes. This will be handy when calling the dialog.