Formik - 如何在确认后重置表单

65
在Formik中,如何使重置按钮仅在确认后重置表单?我的以下代码在单击取消时仍会重置表单。

Formik 中,如何使重置按钮仅在确认后重置表单?

即使您单击“取消”,下面的代码仍然会重置表单。

var handleReset = (values, formProps) => {
    return window.confirm('Reset?'); // still resets after you Cancel :(
};

return (
  <Formik onReset={handleReset}>
    {(formProps) => { 
      return (
        <Form>
          ...
          <button type='reset'>Reset</button>
        </Form>
      )}}
  </Formik>
);
9个回答

165

你好 @Aximili,你可以在 onSubmit 中使用 resetForm 方法。

onSubmit={(values, { resetForm }) => {

      // do your stuff 
      resetForm();

}}

resetForm可以做什么?

可以强制重置表单。这将清除错误和已触摸的状态,将isSubmitting设置为false,isValidating设置为false,并使用当前WrappedComponent的props或传递的参数重新运行mapPropsToValues。后者在componentWillReceiveProps中调用resetForm时非常有用。


这个答案比OP接受的那个更好。 - Dico Didiraja

21

我不是很确定,但我认为您需要编写自己的复位函数,而无需使用带有 reset 类型的按钮。类似这样:

const handleReset = (resetForm) => {
  if (window.confirm('Reset?')) {
    resetForm();
  }
};

function Example() {
  return (
    <Formik initialValues={{ value: 1 }}>
      {formProps => {
        return (
          <Form>
            <Field name="value" type="number" />
            <button
              onClick={handleReset.bind(null, formProps.resetForm)}
              type="button"
            >
              Reset
            </button>
          </Form>
        );
      }}
    </Formik>
  );
}
如果你真的想使用onReset,我认为唯一的方法是抛出一个错误。Formik的源代码似乎表明,无论你的onReset()函数返回什么,resetForm()都将被调用。
const handleReset = () => {
  if (!window.confirm('Reset?')) {
    throw new Error('Cancel reset');
  }
};

function Example() {
  return (
    <Formik initialValues={{ value: 1 }} onReset={handleReset}>
      {formProps => {
        return (
          <Form>
            <Field name="value" type="number" />
            <button type="reset">
              Reset
            </button>
          </Form>
        );
      }}
    </Formik>
  );
}

个人而言,我仍然会选择第一种解决方案。


1
谢谢MadScone。是的,你可以这样做,但是Formik已经有了onReset,所以我认为应该有一种方法在那里完成它。 - Aximili
我更新了我的答案,如果你真的想使用onReset,我提供了一个可能的解决方案。 - Ciarán Tobin
非常感谢您查看源代码,这似乎是Formik的限制。我会采用您的第一个解决方案 :) - Aximili

17

我知道OP的问题是关于Formik的。

不过,对于任何使用useFormik钩子并希望在“重置”按钮点击时清除表单的人,这里有一种方法可以实现。

<button type="reset" onClick={ e => formik.resetForm()}> 重置 </button>


3
我来到这篇文章是为了寻找这个答案。因为React Hooks,这正是我所需要的。 - CokoBWare

6

在2023年

formik.resetForm(); 这个方法对我很有用。

下面是onSubmit事件的完整代码:

  onSubmit:(values)=>{
const name = values.name;
      const mobile = values.mobile;
      const website = values.website;
      const service = values.service;
      const msg = values.msg;
  
axios.post('/api/SendContactForm', {name, mobile, website, service, msg})
      .then(function (response) {
           //console.log(response);
              toast.success(' Thanks for the message. We will contact you asap.');
              formik.resetForm();
          })
          .catch(function (error) {
            console.log(error);
            formik.resetForm();
            toast.error(error.message || error.statusText);
          });
     
  
      }
  
  });


你可以通过在 Promise 中添加一个 finally 回调处理程序来简化代码,以重置表单,这样你就不需要重复执行了。 - Peter Hägg

4

以下是解决方案:

<Formik
initialValues={initialValues}
onSubmit={async (values, { resetForm }) => {
  await onSubmit(values)
  resetForm()
}}>

提交表单后立即重置。

我没有在 Formik 周围使用自定义包装器。


1
如果您不需要像OP请求的按钮,那么这很棒。 我最终做了类似于这样的事情,但在“const onSubmit”声明中。 而且我想保留填充的表单数据,所以只需执行actions.setSubmitting(false),而不是重置整个表单。 - C-Note187

3

我的问题是我不想使用 window.confirm()。我想使用我自己的模态框,所以我使用了

useFormikContext()

您可以创建一个如下的函数组件

let resetPresForm = {};// You will have to define this before useEffect

const ResettingForm = () => {
    const { resetForm } = useFormikContext();
    resetPresForm = resetForm; // Store the value of resetForm in this variable
    return null;
};

现在将这个函数组件导入到您的代码中。

<Formik>
     <button type="button" onClick={() => { setShowResetModal(true) }} className="comman-btn">Reset</button>
     <ResettingForm />
</Formik>

现在,在模态组件确认框中,您可以

const resetPrescriptionForm = () => {
    setShowResetModal(false);
    resetPresForm();
}

参考资料

(此链接为英文原版)

1

我使用了actions.resetForm(),问题得到了解决。

onSubmit={(values, actions) => {

     actions.resetForm();

}}

0
     onSubmit: async (values, actions) => {
    actions.resetForm();
  },

您需要添加两个参数并使用第二个参数。因此,您可以尝试 actions.resetForm();


0
在我的情况下,我创建了一个Formik事件,其中包含onReset={handleFormReset},并且在表单属性中,像这样传递了handleReset用于表单的onReset事件-
            <Formik
            onSubmit={handleFormSubmit}
            initialValues={initialValues}
            validationSchema={checkoutSchema}
            onReset={handleFormReset}
        >
            {({
                values,
                errors,
                touched,
                handleBlur,
                handleChange,
                handleSubmit,
                handleReset
            }) => (
                <form onSubmit={handleSubmit} onReset={handleReset}>

然后我创建了一个类型为“reset”的按钮,如下所示:

<Button type="reset" color="warning" variant="contained" sx={{ mr: 3 }}>
   Reset
</Button>

最后,我创建了名为handleFormReset(values)的处理程序函数,在其中如果用户在确认框中确认,就会清空值对象。
    const handleFormReset = values => {
    if (window.confirm("Do You Want To Reset?")) {
        values = {};
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接