redux-form: SET_SUBMIT_SUCCEEDED called from empty onSubmit and after stopSubmit with errors
I’m not returning a Promise from my onSubmit
, instead dispatching an action to be later picked up in a saga.
The saga calls, startSubmit('formName')
, and then at some point later calling stopSubmit('formName', errors)
(or just stopSubmit('formName')
if everything was ok).
In the case of a failure, the errors
are being properly picked up and applied to the form, however, I’m seeing the @@redux-form/SET_SUBMIT_SUCCEEDED
action coming through as well, which results in an inconsistent form state. The submit failed, but @@redux-form/SET_SUBMIT_SUCCEEDED
is setting submitSucceeded
to true even though I signalled a failed submission.
I’m trying to signal a failure, but the action sequence I’m getting is,
What’s more, I get the @@redux-form/SET_SUBMIT_SUCCEEDED
action creeping in even if I do nothing at all in onSubmit
, i.e. with an empty onSubmit
function that does nothing and doesn’t even return a Promise I see the following action,
In terms of correctness, correct me if I’m wrong, but I feel like this action shouldn’t be being called after an empty onSubmit
that doesn’t return a Promise. In that case shouldn’t nothing have happened? A Promise wasn’t returned, and startSubmit()
wasn’t called so why is Redux Form flipping submitSucceeded
to true
?
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 7
- Comments: 41 (8 by maintainers)
Proposal
A new function, like
handleSubmit
, calleddispatchSubmit
, that you use like this:It will check that sync validation and async validation all passes, and if and only if the form is valid, it will dispatch an action that looks something like:
The
redux-form
reducer will ignore this action entirely. It will be up to all your fancy async middlewares to dispatchstartSubmit()
,stopSubmit()
, etc. to update the form’s submitting state manually.Would that satisfy everyone’s needs?
@erikras This looks interesting, though still feels a lot like hack and adds complexity. If there is still interest, I might get a PR going for the
dispatchSubmit
.In case it’s useful, here is my workaround.
I just return a Promise, and handle resolution/rejection in the main
submitFormSaga
:Action creator
Form
sagas/form.js
FWIW, here’s the watcher saga (which calls submitAddressForm which itself calls
submitFormSaga
) and the data submit saga (called insidesubmitFormSaga
):In result, here’s the actions dispatched, in the expected order:
This might not be the most straightforward way of doing it, but at least :
redux-form-actions
or other packages force you to doI honestly don’t know enough about RF to try to implement the feature so we don’t have to use workarounds, and I’m lacking time, but if someone is willing to work with me on this, that’d be great
Here is the PR for this behavior https://github.com/erikras/redux-form/pull/4015 All existing tests are passing and changes should be backwards compatible. Would be great to hear opinions on the matter and if there are any pitfalls I am unaware of. If everything is OK in approach and implementation, create tests for added functionality and ready to go.
I’m also facing this issue. Using actions to handle async submission with
redux-logic
, similar to the above-mentionedredux-saga
use cases.@erikras your
dispatchSubmit
proposal looks like it would provide the functionality to handle the form easily.This proposal would be perfect for my current project. Any news on this?
For all of you using
redux-saga
, perhaps check out this tool I just built to convert actions into aPromise
for libraries likeredux-form
.Trying to handle both sync and remote/async submit workflows via a single
onSubmit
handler, and forking the two behaviours based on the return type from that function feels like a slightly fuzzy public api. Is there any benefit to be gained by having something more explicit?Afaiu returning a promise from this handler is quite hostile to approaches that use libs that fully abstract such workflows like redux-observable and redux-saga.
Perhaps an
onSubmit
for sync workflows that is sensitive to errors being thrown, and anonSubmitAsync
(or whatever) for async workflows where all of the submit handling is expected to be handled remotely via action creators?I’ve got time and a desire to work on this and prepare a PR if the maintainers think there’s some benefit to be gained here …
I feel like there’s almost 100% perfect saga support as is (and indeed redux-thunk support, since it suffers from the same issue).
I setup my form like so,
and then whether the
submit
action creator is handled exclusively by a thunk, or triggers a saga, the approach is similar. The logic (in this case a saga) looks like,So remote controlling the form like this with action creators basically almost already works 100%, and I don’t see how you’d achieve better separation of concerns. The problem being just the (fairly minor) inconsistency in the form’s state that I mentioned at the top of this thread with
submitSucceeded
flipped totrue
- since as you rightly pointed out the submit handling logic is erroneously assumed synchronous.This feels like something that could be fixed?
So I’m another one who tried to do form submission in “redux way” (my middleware is redux-observable). I found proposed solutions hard to understand and maintain, but original one is really what we need.
Since I have just a few relatively simple forms, I ended up with rewriting code with formik and own redux integration. Integration is not really hard, and because formik uses TypeScript - it integrates better with project written in TypeScript.
I wish someday redux-form can be used with pure redux approach without pain, and replaced flow with TypeScript.
Hi Guys,
Any progress on this? I just started using redux-form and I have run into the same issue. I have found a sort of way to handle it, but I am not sure it is the best way. it looks like a little hack to me. If someone is interested it is this library: https://github.com/salsita/redux-form-actions
this takes advantage of the fact onSubmit can handle a promise as well.
I think it would be a much cleaner approach if one could define which action the form
Thanks