Search code examples
reactjsformsformik

Formik - How to reset form after confirmation


In Formik, how to make the Reset button reset the form only after confirmation?

My code below still resets the form even when you click Cancel.

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>
);

Solution

  • I'm not completely certain, but I think you will have to write your own reset function without a button with a reset type. Something like this:

    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>
      );
    }
    

    If you really want to use onReset, I think the only way is to throw an error. The Formik source code seems to indicate resetForm() will be called no matter what your onReset() function returns.

    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>
      );
    }
    

    I would still go with the first solution though personally.