I have created a custom React hook to use MUI Dialog using React Context API. However, I need to return some value from Dialog, like if the OK button has been clicked. But I have some troubles.
Here is code snippet from context provider:
const showAlertDialog = (title: string, text?: string): Promise<boolean> => {
setOpen(true);
setTitle(title);
setText(text);
return new Promise<boolean>((resolve: (value: boolean) => void) => {
setActionCallback(resolve);
});
};
const handleOKClick = () => {
setOpen(false);
actionCallback?.(true);
};
return (
<DialogContext.Provider value={{ showAlertDialog }}>
{children}
<DialogContainer
title={title}
open={open}
text={text}
onOK={handleOKClick}
></DialogContainer>
</DialogContext.Provider>
);
}
export const useMuiDialog = () => {
return useContext(DialogContext);
};
However when I call the await showAlertDialog form onClick handler, it immediately returns without waiting for promise to resolve/reject:
const handleClick = async () => {
console.log('dialog');
const answer = await showAlertDialog('test', 'test');
console.log(answer);
};
I am not getting something here, but I don't know what...
The whole example can be found on:
https://stackblitz.com/edit/react-bk1d19?file=demo.tsx
Thank you
CodePudding user response:
hope you are doing well! I would do this in a very simple way, and it's by passing the setState from the Parent component of the dialog.
Let's say we have the Parent component named Parent:
const Parent = () => {
const [value, setValue] = useState("");
return <Dialog setValue={setValue}/>
In the dialog I would simply do:
const Dialog = ({setValue}) => {
const handleOk = () => setValue("OK");
const handleCancel = () => setValue("Cancel");
return ...
}
And like that you can read the value "Ok" or "Cancel" from the parent component.
PS: Of course you should add the setState of the opening and closing of the dialog.
CodePudding user response:
What could be happening is this:
setActionCallback(resolve);
You think you didn't invoke resolve
here because you store it in state, but when you call set state in react with a function, react thinks you are using set state with updater function; from the docs:
If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.
So it probably immediately invoked the resolve
function.