Repository: jaredpalmer/formik
Pull request #451 (2018-02-22 17:26:20)

Allow handleSubmit to be called without preventDefault
In some use cases handleSubmit could be called without having access to a ReactEvent, for example when being invoked from a custom component or ReactNative.  Currently handleSubmit expected to be called with an object containing a preventDefault method and it would throw an error if called without one.

Added a test and modified the code to simply check for existence before attempting to call.

jaredpalmer: LGTM. Thanks for writing the test
jeffbski: I'm not sure why the travis build failed. Test works locally. Any ideas?

jaredpalmer: Not sure need to figure that out.
jeffbski: looks like it might be failing in FastField, missing import?
jeffbski: It is a case sensitive issue that started here https://github.com/jaredpalmer/formik/commit/6c3e0627e9e1463b3ef5629eff913a2b9b68878b

I'll create a PR to attempt to fix it.
jaredpalmer: I think you are right.
jeffbski: I'll rebase with master to pick up the rename fix
jeffbski: yay! That worked.

Patch:
diff --git a/README.md b/README.md
index 40d5897..ca1a957 100644
--- a/README.md
+++ b/README.md
@@ -326,7 +326,7 @@ npm install yup --save
       - [`handleBlur: (e: any) => void`](#handleblur-e-any--void)
       - [`handleChange: (e: React.ChangeEvent<any>) => void`](#handlechange-e-reactchangeeventany--void)
       - [`handleReset: () => void`](#handlereset---void)
-      - [`handleSubmit: (e: React.FormEvent<HTMLFormEvent>) => void`](#handlesubmit-e-reactformeventhtmlformevent--void)
+      - [`handleSubmit: (e: React.FormEvent<HTMLFormEvent> | undefined) => void`](#handlesubmit-e-reactformeventhtmlformevent--void)
       - [`isSubmitting: boolean`](#issubmitting-boolean)
       - [`isValid: boolean`](#isvalid-boolean)
       - [`resetForm: (nextValues?: Values) => void`](#resetform-nextvalues-values--void)
diff --git a/src/Formik.tsx b/src/Formik.tsx
index ce24c39..b9800de 100644
--- a/src/Formik.tsx
+++ b/src/Formik.tsx
@@ -490,8 +490,10 @@ export class Formik<ExtraProps = {}, Values = object> extends React.Component<
     );
   };
 
-  handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
-    e.preventDefault();
+  handleSubmit = (e: React.FormEvent<HTMLFormElement> | undefined) => {
+    if (e && e.preventDefault) {
+      e.preventDefault();
+    }
     this.submitForm();
   };
 


Test patch:
diff --git a/test/formik.test.tsx b/test/formik.test.tsx
index 7494a38..3f55d3d 100644
--- a/test/formik.test.tsx
+++ b/test/formik.test.tsx
@@ -256,6 +256,38 @@ describe('<Formik>', () => {
         expect(preventDefault).toHaveBeenCalled();
       });
 
+      it('should not error if called without an object', () => {
+        const FormNoEvent = (
+          <Formik initialValues={{ name: 'jared' }} onSubmit={noop}>
+            {({ handleSubmit }) => (
+              <button onClick={() => handleSubmit(/* undefined event */)} />
+            )}
+          </Formik>
+        );
+        const tree = mount(FormNoEvent);
+        const fn = () => {
+          tree.find('button').simulate('click');
+        };
+        expect(fn).not.toThrow();
+      });
+
+      it('should not error if called without preventDefault property', () => {
+        const FormNoPreventDefault = (
+          <Formik initialValues={{ name: 'jared' }} onSubmit={noop}>
+            {({ handleSubmit }) => (
+              <button
+                onClick={() => handleSubmit({} /* no preventDefault */)}
+              />
+            )}
+          </Formik>
+        );
+        const tree = mount(FormNoPreventDefault);
+        const fn = () => {
+          tree.find('button').simulate('click');
+        };
+        expect(fn).not.toThrow();
+      });
+
       it('should touch all fields', () => {
         const tree = shallow(BasicForm);
         tree