React MUIDialogContext 在关闭时无法正确解析 Promise。数据未发送回组件

问题描述 投票:0回答:1

我正在尝试创建一个对话框上下文以允许可重用的对话框。我还尝试让它在关闭时返回一个值,以将该数据传递给需要它的组件。

这是 DialogContext 的相关部分:

...
const defaultValue: DialogParams = { open: false, children: null };

export default function DialogProvider({ children }) {
    const [dialog, setDialog] = useState<DialogParams>(defaultValue);
    const [resolver, setResolver] = useState<((value: any) => void) | null>(null);

    const theme = useTheme();
    const fullscreen = useMediaQuery(theme.breakpoints.down('md'));


    function openDialog(options: Omit<DialogParams, "open">): Promise<any> {
        setDialog({ ...options, open: true });
        return new Promise((resolve: (value: any) => void) => {
            setResolver(() => resolve);
        });
    }

    const closeDialog: DialogReturnProps = (props?: any) => {
        if (resolver) {
            resolver(props);
        }
        setResolver(null);
        setDialog(defaultValue);
    }

    const dialogContextObj: DialogState = [openDialog, closeDialog];

    return <DialogContext.Provider value={dialogContextObj}>
        {children}
        {
            <Dialog fullScreen={fullscreen} open={dialog.open} onClose={() => closeDialog()}>
                {
                    <div className="grid"><IconButton className="justify-self-end" onClick={() => closeDialog()}><Close color="error" /></IconButton></div>
                }
                {dialog.children}
            </Dialog>
        }
    </DialogContext.Provider>
}

这是我目前的使用方式:

const addPlayerDialogRef = useRef(AddPlayerDialog);
const [openDialog, closeDialog] = useDialog();
...
const val = await openDialog({
    children: <AddPlayerDialog handleSubmit={closeDialog} ref={addPlayerDialogRef} />
});
console.log("HERE", val);
if (val) {
   await playerCtx.addPlayers([val]);
   await refresh();
}
...

还有addPlayerDialog:

const AddPlayerDialog = forwardRef<any, { handleSubmit: DialogReturnProps }>(function AddPlayerDialog(props, _) {
    const { handleSubmit } = props;
...
 function addPlayer(ev: FormEvent<HTMLFormElement>) {
        ev.preventDefault();

        const data = new FormData(ev.target as HTMLFormElement)
        if (data.get("firstName") && data.get('lastName') && data.get('gender')) {
            const player: Player = {
                firstName: data.get('firstName')! as string,
                lastName: data.get('lastName')! as string,
                rating: data.get('rating') ? parseInt(data.get('rating')!.toString()) : 0
            };
            handleSubmit(player);
        }
    }

基本上,我处理 AddPlayerDialog 中的所有验证,当需要关闭对话框时,我调用handleSubmit 函数(应该是 closeDialog 函数),这应该解决承诺。然而,我遇到的问题是,一半的时间它工作正常,而另一半的时间解析器为空。我不太确定为什么它会为空,尤其是当我们在 openDialog 函数中设置它时。当我尝试单击对话框上的“x”按钮关闭而不发送值,然后重新打开它并尝试填写表单并提交时,我总是可以打破它。

promise react-context
1个回答
0
投票

Roar S.的回答解决了我的问题。我从 useState 更改为 useRef,这使得它可以工作。我不是 100% 确定为什么它之前不起作用,但这确实有效。

这是我所做的更改:

在我更改的对话框上下文中:

const [resolver, setResolver] = useState<((value: any) => void) | null>(null);

let resolver = useRef<((value: any) => void) | null>(null);

打电话/更新时我做了:

resolver.current(props);

   return new Promise((resolve: (value: any) => void) => {
            resolver.current = resolve;
        });
© www.soinside.com 2019 - 2024. All rights reserved.