Formik: setSubmitting not working

Created on 29 Oct 2019  路  29Comments  路  Source: formium/formik

馃悰 Bug report

Current Behavior

setSubmitting method not changing FormikProps isSubmitting

Your environment

| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 2.0.3
| React | 16.10.2
| TypeScript | 3.6.4
| Browser | Opera
| npm/Yarn | 1.19.1
| Operating System | Windows10

Most helpful comment

Experiencing a similar issue. isSubmitting is automatically getting set back to false in V2. According to the docs and the behavior in V1, isSubmitting must manually be set to false in the handler.

All 29 comments

Experiencing a similar issue. isSubmitting is automatically getting set back to false in V2. According to the docs and the behavior in V1, isSubmitting must manually be set to false in the handler.

same problem

I first thought that my form has some issues. After debugging I can say that setSubmitting is working but the issue is that isSubmitting set back to false after handleSubmit get executed.

I first thought that my form has some issues. After debugging I can say that setSubmitting is working but the issue is that isSubmitting set back to false after handleSubmit get executed.

true, need to create for example promise or async and await for response submit,

Full example
https://codesandbox.io/s/formik-v2-template-9j5xz

I'm also experiencing this issue. the docs say when you call handleSubmit(e) isSubmitting is set to true. This is indeed happening, but it is immediately getting set to false right after for some reason.

It appears from the source that the submit handler is now expecting a Promise and Formik will set the isSubmitting state back to false when the promise resolves. If the submit handler is not a promise it resolves immediately.

Is this the new API of V2?

I am now returning my promise handler and its now working, but I dont like this approach, because if you have chain promises, then isSubmitting will return false on the first promise, and basically the loading indicator will go away, but theres still more promises to fulfill afterwards. I'd prefer to manually reset isSubmitting, or add a flag to not auto update isSubmitting to false

Can someone fix this or change the documentation, please? This is basic functionality for most forms and I went almost insane trying to figure out what was wrong 馃槄

It's a bit unclear which behaviour is the intended one for version 2. If we can get some clarification I'd be happy to create a pull request.

It's a bit unclear which behaviour is the intended one for version 2. If we can get some clarification I'd be happy to create a pull request.

@Tigge For what it's worth, my vote would be to duplicate as closely as possible the behavior of Version 1, since I believe this would alleviate the need to refactor code to address this issue and in turn make migration to Version 2 as seamless as possible.

Just as an example, I have been using isSubmitting in my fields and buttons to disable functionality.
However, after migrating to Version 2, I now get a weird effect where my fields and buttons are made active for a split second before I have an opportunity to transition away. From a strictly selfish perspective, I'd hate to have to refactor all these forms in order to stay current with the latest version of Formik.

68047456-adf29f00-fc9b-11e9-9f51-ed999ebb6968

You should need to return a promise I thought. Manual setSubmitting calls should still work (mimic v1 behavior)

@jaredpalmer: Previous behaviour is here https://github.com/jaredpalmer/formik/blob/version-1.5.8/src/Formik.tsx#L444. Nothing in formik touched the isSubmitting flag in version 1. You had to reset it yourself once you where done submitting. In the documentation this is also mentioned:

_you call_ setSubmitting(false) in your handler to finish the cycle

In version 2 the behaviour is here https://github.com/jaredpalmer/formik/blob/master/src/Formik.tsx#L713, once your onSubmit function is done, resolved or rejected doesn't matter, formik will reset it to false for you.

I agree with @kbi-daniel that following version 1 behaviour would be nice - at least if you want to make the transitioning easier. If not - at least one of rejecting or resolving should keep the isSubmitting state.

Also the onSubmit function is typed as onSubmit: (values: Values, formikHelpers: FormikHelpers<Values>) => void now.

And it's also very annoying when you expect an async result from a Redux state.

Please allow us to disable this new behaviour of isSubmitting and allow us to use setSubmitting again.

I've created a pull request (#1987) to revert the behaviour to how it functioned in version 1. If we want some other behaviour I'd be happy to adjust it or create a new pull request.

It will introduce a subtle bug that user can still click the button when you direct user to another page after the promise is fulfilled.

const onSubmit = (...) => {
  return submit(...).then(() => {
     Router.push(...) // The button is already enabled so user can click the button again. 
  })
}

I'm seeing this issue in v2 as well. I see there's a PR to change it back to v1 behavior which I support.

Yeah I've also face the same issue in my latest project where I install the formikverison 2.0.3 where isSubmitting is not working and I switched back to the previous version 1.5.8 and it works for me.

Same here. I've switched back to v1.5.8 for now. I hope the PR gets will get merged soon!

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

I'm using redux saga to handle side effects so my method returns immediately after dispatching my actions and later on as part of my saga I'd setSubmitting to false

This was confusing as well. I think the doc should at least be updated to indicate a Promise needs to be returned for it to work as indicated.

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

This is ideal and easy to implement. Can someone open a PR?

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

This is ideal and easy to implement. Can someone open a PR?

@jaredpalmer but should there not be a way to keep the form in an unsubmitted state in the new promise version?

I've updated my PR to enable both old + new behavior. The documentation is not updated yet there. However I don't think that is a good solution.

I can understand having isSubmitting as an internal state, only being true while the onSubmit handler runs. In that case there might be no need to have the setSubmitting function available either.

The use case for the old method was also to have it as a this form is submitted and should not be submittable again.

Either continue only with v2, allow it to be left in an isSubmitting state or just add an example on how to mimic that use case with react state or similar. And in either case, clarify how things really work in the documentation.

Either way (even if we do the dual version) I'll continue to update the PR.

Fixed in 2.1

Fixed in 2.1

Causing issue in "formik": "^2.1.4"

I can still repro this on 2.1.4 as well. See https://codesandbox.io/s/formik-codesandbox-template-6b1s9?file=/index.js

The current docs are accurate:

IMPORTANT: If onSubmit is async, then Formik will automatically set isSubmitting to false on your behalf once it has resolved. This means you do NOT need to call formikBag.setSubmitting(false) manually. However, if your onSubmit function is synchronous, then you need to call setSubmitting(false) on your own.

So either this issue should be re-opened, or we should accept the new behavior.

i solved like this:

  const onSubmitClickHandler = (data, { setSubmitting }) => {
    const submit = async () => {
      const isAuthenticated = await props.signInWithEmailAndPassword(data);
      setSubmitting(false);
      if (isAuthenticated) history.push('/dashboard/menu-list');
    };
    submit();
  };

  return (    
      <Formik
        initialValues={initialValues}
        validationSchema={createSignInSchema(FormValidationErrors)}
        onSubmit={onSubmitClickHandler}
      >

I think it can be a workaround

i solved like this:

  const onSubmitClickHandler = (data, { setSubmitting }) => {
    const submit = async () => {
      const isAuthenticated = await props.signInWithEmailAndPassword(data);
      setSubmitting(false);
      if (isAuthenticated) history.push('/dashboard/menu-list');
    };
    submit();
  };

  return (    
      <Formik
        initialValues={initialValues}
        validationSchema={createSignInSchema(FormValidationErrors)}
        onSubmit={onSubmitClickHandler}
      >

I think it can be a workaround

Thanks! This was the solution for me.

Was this page helpful?
0 / 5 - 0 ratings