typescript 如何防止对话框消失?Reactjs

zphenhs4  于 6个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(95)

在这段代码中,我显示的弹出窗口有按钮,当按钮负责取消点击确认对话框显示。我希望弹出窗口消失时,点击它外面,所以我这样处理它:

const popupRef = useRef<HTMLDivElement>(null);

  const handleClickOutside = (event: MouseEvent) => {
    if (
      popupRef.current &&
      !popupRef.current.contains(event.target as Node)
    ) {
      onClose();
    }
  };
  

  useEffect(() => {
    document.addEventListener('mousedown', handleClickOutside);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, []);

字符串
onClose是关闭弹出窗口的回调函数。现在,当按钮被点击时,我会创建这样的对话框:

{showCancelConfirmationDialog && 
      <CancelConfirmationDialog 
      onCancel={handleCloseDialog} 
      onConfirm={handleCancelReservation} 
      name={block.lessonWith} 
      time={chosenTime} 
      date={block.day} />}

  const handleCloseDialog = () => {
    console.log("closing");
    setShowCancelConfirmationDialog(false);
  }

  const handleCancelReservation = () => {
    console.log("block")
    block.isReserved = false;
    block.reservedBy = "notMe";
    onClose();
  }


对话框代码:

interface DeleteConfirmationDialogProps {
  onCancel: () => void;
  onConfirm: () => void;
  name: string;
}

const DeleteConfirmationDialog: React.FC<DeleteConfirmationDialogProps> = ({ onCancel, onConfirm, name }) => {
  return (
    <div className="delete-confirmation-dialog">
      <p className='delete-confirmation-dialog-p'>Te jazdy są zarezerwowane przez: {name} </p>
      <p className='delete-confirmation-dialog-p'>Czy na pewno chcesz je przesunąć i powiadomić o tym kursanta?</p>
      <button className='delete-confirmation-dialog-button' onClick={onConfirm}>Usuń i powiadom</button>
      <button className='delete-confirmation-dialog-button' onClick={onCancel}>Anuluj</button>
    </div>
  );
}

export default DeleteConfirmationDialog;


现在的问题是,无论我点击哪里,所有的东西都消失了,因为useEffecthandleClickOutside无论如何都会被触发,我不知道它发生了什么。如果我注解掉这段代码,它就可以正常工作。我试图为对话框添加另一个popupRef,但它不起作用。我还试图在对话框处于活动状态时通过布尔值控制它,但它也不起作用。

70gysomp

70gysomp1#

也许最好的选择是使用现成的组件,比如Material-UI的Dialog
你可以找到更多的信息与良好的例子here

olqngx59

olqngx592#

我已经检查了你上面的代码。
我觉得这里面有些问题

const handleClickOutside = (event: MouseEvent) => {
    if (
      popupRef.current &&
      !popupRef.current.contains(event.target as Node)
    ) {
      onClose();
    }
  };

字符串
这是我的新代码。

const handleClickOutside = (event: MouseEvent) => {
  if (
     !popupRef.current ||
     popupRef.current.contains(event.target as Node)
   ) {
    return;
  }
  onClose();
};


此外,您还需要触发touchstart事件来关闭modal。

document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('touchstart', handleClickOutside);

document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('touchstart', handleClickOutside);


如果你还有什么问题的话就告诉我。
我希望我的代码对你有用。
谢谢

bmvo0sr5

bmvo0sr53#

我找到了答案,只需像这样添加新的useRef:

const popupRef = useRef<HTMLDivElement>(null);
  const cancelDialogRef = useRef<HTMLDivElement>(null);

  const handleClickOutside = (event: MouseEvent) => {
    if (
      popupRef.current &&
      !popupRef.current.contains(event.target as Node)&&
      !cancelDialogRef.current?.contains(event.target as Node)
    ) {
      onClose();
    }
  };

  useEffect(() => {
    document.addEventListener('mousedown', handleClickOutside);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, []);

字符串
在这里将其 Package 成div

<div ref={cancelDialogRef}>
      {showCancelConfirmationDialog &&
        <CancelConfirmationDialog
          onCancel={handleCloseDialog}
          onConfirm={handleCancelReservation}
          name={block.lessonWith}
          time={chosenTime}
          date={block.day} />}
      </div>


现在它工作正常

相关问题