MUI-如何以强制/编程方式打开对话框

MUI - How to open Dialog imperatively/programmatically(MUI-如何以强制/编程方式打开对话框)

本文介绍了MUI-如何以强制/编程方式打开对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常这是您使用MUI的方式Dialog。以下代码摘自文档:

export default function AlertDialog() {
  const [open, setOpen] = React.useState(false);
  const handleClickOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button variant="outlined" color="primary" onClick={handleClickOpen}>
        Open Dialog
      </Button>
      <Dialog open={open} onClose={handleClose}>
       {...}
      </Dialog>
    </div>
  );
}

但我希望它必须创建Dialog,有点像火和遗忘。我不想在需要创建其他组件时将Dialog组件嵌入到其他组件中。理想情况下,我想这样称呼它

createDialog(<>
   <h1>My Dialog</h1>
   <span>My dialog content</span>
   <button onClick={() => closeDialog()}>Close</button>
</>)

因此我的组件定义将如下所示

const createDialog = () => {
   // ???
}
const closeDialog = () => {
   // ???
}
export default function AlertDialog() {
  const [open, setOpen] = React.useState(false);
  const handleClickOpen = () => setOpen(true);
  const handleClose = () => {
     createDialog(<>
        <h1>My Dialog</h1>
        <span>My dialog content</span>
        <button onClick={() => closeDialog()}>Close</button>
     </>)
  };

  return (
    <Button variant="outlined" color="primary" onClick={handleClickOpen}>
      Open Dialog
    </Button>
  );
}

推荐答案

您可以使用Reaction的Provider模式重用对话框。官方的Reaction文档已经做了很详细的解释,所以我在此不再赘述。

首先创建一个自定义的Provider组件,在本例中,我将调用DialogProvider。此组件将管理处于本地状态的Dialog的列表。

const DialogContext = React.createContext();

export default function DialogProvider({ children }) {
  const [dialogs, setDialogs] = React.useState([]);

  return (
    <DialogContext.Provider {...}>
      {children}
    </DialogContext.Provider>
  );
}

如您所见,我们这里有一个对话框数组,它包含呈现时将映射到实际<Dialog />组件的对话框道具。

export default function DialogProvider({ children }) {
  const [dialogs, setDialogs] = React.useState([]);

  return (
    <DialogContext.Provider {...}>
      {children}
      {dialogs.map((dialog, i) => {
        return <DialogContainer key={i} {...dialog} />;
      })}
    </DialogContext.Provider>
  );
}
<DialogContainer/><Dialog/>的父组件。将您想要重用的任何内容都放入其中。以下是您入门的最小示例。

function DialogContainer(props: DialogContainerProps) {
  const { children, open, onClose, onKill } = props;

  return (
    <Dialog open={open} onClose={onClose} onExited={onKill}>
      {children}
    </Dialog>
  );
}

我们可以照常使用setState创建和删除对话框。

const [dialogs, setDialogs] = React.useState([]);

const createDialog = (option) => {
  const dialog = { ...option, open: true };
  setDialogs((dialogs) => [...dialogs, dialog]);
};

const closeDialog = () => {
  setDialogs((dialogs) => {
    const latestDialog = dialogs.pop();
    if (!latestDialog) return dialogs;
    if (latestDialog.onClose) latestDialog.onClose();
    return [...dialogs].concat({ ...latestDialog, open: false });
  });
};
但是,当我们在这里定义它们时,我们如何在其他组件中调用它们呢?请记住,我们在这里使用的是Provider组件,这意味着我们可以向下传递上下文数据,以便其他组件可以引用,在本例中,我们希望向下传递createDialogcloseDialog

const [dialogs, setDialogs] = React.useState([]);
const createDialog = (option) => {/*...*

本文标题为:MUI-如何以强制/编程方式打开对话框