Let’s start off with the problem. I manage a few popular form libraries, and I often get the question:
How can I use
redux-saga
orredux-observable
to submit my form via a side-effect?
I have to answer, “Well… the form library is expecting the onSubmit
function
to return a Promise
to know when it is submitting, so...” At least with
Redux Form, because all of its state was managed in
Redux, including whether or not the form was currently being submitted, it was
possible to let users dispatch the START_SUBMIT
and STOP_SUBMIT
actions
themselves, rather than allowing Redux Form to manage that for them via the
Promise
. But, if you
take your form state out of Redux, you’re just
sort of screwed…
Until now.
What if you had a way to create an asynchronous function that dispatched a START
action when it was called, and resolved or rejected the returned Promise
when
either a RESOLVE
or REJECT
action was dispatched? That would totally solve
this problem. Right?
💥 React Redux Promise Listener 💥
The name is not the catchiest on NPM, but... I’ve just released React Redux Promise Listener, a library that solves just this problem. The API looks something like this:
<MakeAsyncFunctionlistener={promiseListener}start="START_ACTION_TYPE" // the type of action to dispatch when this function is calledresolve="RESOLVE_ACTION_TYPE" // the type of action that will resolve the promisereject="REJECT_ACTION_TYPE" // the type of action that will reject the promise>{(asyncFunc) => (<SomeFormLibrary onSubmit={asyncFunc}>...<button type="submit">Submit</button></SomeFormLibrary>)}</MakeAsyncFunction>
The promiseListener
comes from a piece of Redux middleware that must be
installed. By default, the values passed around are kept in action.payload
,
but there are config options that let you read and write those from anywhere in
the actions.
Conclusion
It should be a lot easier now to use async side-effect Redux libraries with other async components, like routers, that were built on the assumption of Promises being “how async is done” in Javascript.
❤️ Enjoy! ❤️