我正在使用 React Final Form 创建表单。我有一个组件,我在其中定义了确认模态框并 promise 处理它。函数实现如下:
function Campaign() {
let resolveConfirm;
let rejectConfirm;
const confirmPromise = new Promise((resolve, reject) => {
resolveConfirm = resolve;
rejectConfirm = reject;
});
const modal = (
<ConfirmModal
name={MODAL_DISABLE_SOCIAL_CAMPAIGNS}
title={t('Confirm Uncheck')}
buttonText={t('Confirm')}
onConfirm={resolveConfirm}
modalEvents={{
onClose: () => {
try {
rejectConfirm();
} catch (e) {}
},
}}
>
<p>{t('Are you sure you want to disable ?')}</p>
</ConfirmModal>
);
return (
<OpenModal modal={modal}>
{(open) => (
<ManageForm
openConfirmModal={({ campaign }, form) => {
const isUnchecked = !campaign?.selected;
// If unchecked the selected checkbox only then
// confirm dialog box should get open
if (isUnchecked) {
open();
return confirmPromise;
}
return false;
}}
>
{(params) => {...
}}
</ManageForm>
)}
</OpenModal>
)
}
'ManageForm' 组件被导入到上面的组件 'Campaign' 中,并且有一个'save' 按钮,点击它会调用提交方法和确认模式打开时带有“取消”和“确认”选项。 'ManageForm' 组件的实现如下:
import { Form } from 'react-final-form';
import Button from 'components/UI/Button';
function ManageForm(){
const {
openConfirmModal
} = props;
}
// This runs when clicked on a save button.
const handleSubmit = (formValues, form) => {
if (openConfirmModal) {
const openPromise = openConfirmModal(formValues, form);
if (openPromise) {
try {
await openPromise;
} catch (e) {
// Don't continue if the user cancelled the opening
return;
}
}
}
// Code after this will run only if openPromise is success.
// Here a network call happens via saveEndpoint method
const response = await saveEndpoint({ ...formValues });
}
return (
<Form
onSubmit={handleSubmit}
>
(formProps) => {
return (
<form>
....
<Button
label={t('button_label.save')}
type="submit"
appearance="brand"
/>
....
</form>
)}
</Form>
);
}
现在,问题发生在用户第一次取消确认模式框后,用户再次单击保存按钮,这次如果单击确认它不起作用。 如果用户第一次登陆页面,点击保存按钮,然后点击确认按钮,在这种情况下它会起作用。它只是在取消一次之后,然后在随后的确认中失败。
我的发现:
当用户第一次取消时,rejectConfirm 被调用并将 confirmPromise 设置为被拒绝,在 ManageForm 的“openPromise”中如果 block 给出 await openPromise 值被拒绝和代码停止。现在当用户再次点击保存按钮时,这一次如果用户试图点击确认,resolvePromise 被调用但是 confirmPromise 的值已经被 rejectConfirm 设置(当用户第一次取消时)并且它仍然保持不变,即被拒绝.所以在 ManageForm 中 await openPromise 再次给我们拒绝和确认不起作用。
在第一次取消时,我如何处理让此工作用于后续确认调用的 promise ? 每当用户取消确认时,我都无法重新呈现我的组件,因为它会删除所有选定的表单值。
谢谢。
最佳答案
我明白你在做什么。您的 promise 值(此处为“confirmPromise”)在您第一次取消确认模式框时被设置为“已拒绝”。之后我假设“Campaign”组件的渲染不会发生并且 confirmPromise 的值保持不变。在随后的确认模态调用中,无论调用 resolveConfirm 还是调用 rejectConfirm,confirmPromise 的值都保持不变。正因为如此,在组件“ManageForm”中,await openPromise 值始终被评估为“rejected”,因此它进入 catch block 并返回,它也退出 handleSubmit 函数,并且永远不会发生进一步的操作。这里发生的事情的简单建模可以是:jsfiddle.net/utr3Lkp0。
如果您检查上面的 fiddle ,那么在 ManageForm 内部, promise 值始终保持在第一次设置时。
在您的情况下,我能想到的是在“Campaign”组件内设置状态,并在设置 promise (取消或确认)时更改其值。它将导致重新呈现组件“Campaign”,并且每次都会有一个新的 promise 。如果您担心初始值会丢失,您可以将它们单独存储在某个地方,然后可以在每次渲染后使用它们来初始化表单。
关于javascript - 基于 React promised 的 Confirm Modal 无法正常工作。一旦用户取消,在随后的模式打开时,即使用户确认,它也会被取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73096116/