Preview:
import { useEffect, useState } from 'react';

interface ConfirmState {
  isOpen: boolean;
  proceed: any;
  cancel: any;
}

interface UseConfirmReturnType extends ConfirmState {
  isConfirm: () => Promise<boolean>;
}

export const useConfirm = (): UseConfirmReturnType => {
  const [confirm, setConfirm] = useState<ConfirmState>({} as ConfirmState);
  const [needsCleanup, setNeedsCleanup] = useState(false);

  const isConfirm = () => {
    setNeedsCleanup(true);
    const promise = new Promise((resolve, reject) => {
      setConfirm({
        isOpen: true,
        proceed: resolve,
        cancel: reject,
      });
    });

    return promise.then(
      () => {
        setConfirm({ ...confirm, isOpen: false });
        return true;
      },
      () => {
        setConfirm({ ...confirm, isOpen: false });
        return false;
      }
    );
  };

  useEffect(() => {
    return () => {
      if (confirm.cancel && needsCleanup) {
        confirm.cancel();
      }
    };
  }, [confirm, needsCleanup]);

  return {
    ...confirm,
    isConfirm,
  };
};
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter