react / redux-form: how to return promise from onSubmit? : <p>I'm trying to wrap my head around <a href="http://rackt.org/redux/" rel="noreferrer">redux</a>, <a href="http://rackt.org/redux/docs/basics/UsageWithReact.html" rel="noreferrer">react-redux</a> and <a href="http://erikras.github.io/redux-form/" rel="noreferrer">redux-form</a>.</p>

<p>I have setup a store and added the reducer from redux-form. My form component looks like this:</p>

<p><strong>LoginForm</strong></p>

<pre><code>import React, {Component, PropTypes} from 'react'
import { reduxForm } from 'redux-form'
import { login } from '../../actions/authActions'

const fields = ['username', 'password'];

class LoginForm extends Component {
    onSubmit (formData, dispatch) {
        dispatch(login(formData))
    }

    render() {
        const {
            fields: { username, password },
            handleSubmit,
            submitting
            } = this.props;

        return (
            &lt;form onSubmit={handleSubmit(this.onSubmit)}&gt;
                &lt;input type="username" placeholder="Username / Email address" {...username} /&gt;
                &lt;input type="password" placeholder="Password" {...password} /&gt;
                &lt;input type="submit" disabled={submitting} value="Login" /&gt;
            &lt;/form&gt;
        )
    }
}
LoginForm.propTypes = {
    fields: PropTypes.object.isRequired,
    handleSubmit: PropTypes.func.isRequired,
    submitting: PropTypes.bool.isRequired
}

export default reduxForm({
    form: 'login',
    fields
})(LoginForm)
</code></pre>

<p>This works as expected, in <a href="https://github.com/gaearon/redux-devtools" rel="noreferrer">redux DevTools</a> I can see how the store is updated on form input and on submitting the form the <code>login</code> action creator dispatches the login actions.</p>

<p>I added the <a href="https://github.com/gaearon/redux-thunk" rel="noreferrer">redux-thunk</a> middleware to the store and setup the action creator(s) for logging in as described in the <a href="http://rackt.org/redux/docs/advanced/AsyncActions.html" rel="noreferrer">redux docs for Async Actions</a>:</p>

<p><strong>authActions.js</strong></p>

<pre><code>import ApiClient from '../apiClient'

const apiClient = new ApiClient()

export const LOGIN_REQUEST = 'LOGIN_REQUEST'
function requestLogin(credentials) {
    return {
        type: LOGIN_REQUEST,
        credentials
    }
}

export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'
function loginSuccess(authToken) {
    return {
        type: LOGIN_SUCCESS,
        authToken
    }
}

export const LOGIN_FAILURE = 'LOGIN_FAILURE'
function loginFailure(error) {
    return {
        type: LOGIN_FAILURE,
        error
    }
}

// thunk action creator returns a function
export function login(credentials) {
    return dispatch =&gt; {
        // update app state: requesting login
        dispatch(requestLogin(credentials))

        // try to log in
        apiClient.login(credentials)
            .then(authToken =&gt; dispatch(loginSuccess(authToken)))
            .catch(error =&gt; dispatch(loginFailure(error)))
    }
}
</code></pre>

<p>Again, in redux DevTools I can see that this works as expected. When <code>dispatch(login(formData))</code> is called in <code>onSubmit</code> in the LoginForm, first the <code>LOGIN_REQUEST</code> action is dispatched, followed by <code>LOGIN_SUCCESS</code> or <code>LOGIN_FAILURE</code>. <code>LOGIN_REQUEST</code> will add a property <code>state.auth.pending = true</code> to the store, <code>LOGIN_SUCCESS</code> and <code>LOGIN_FAILURE</code> will remove this property. (I know this might me something to use <a href="https://github.com/rackt/reselect" rel="noreferrer">reselect</a> for, but for now I want to keep it simple.</p>

<p>Now, in the redux-form docs I read that I can return a promise from <code>onSubmit</code> to update the form state (<code>submitting</code>, <code>error</code>). But I'm not sure what's the correct way to do this. <code>dispatch(login(formData))</code> returns <code>undefined</code>.</p>

<p>I could exchange the <code>state.auth.pending</code> flag in the store with a variable like <code>state.auth.status</code> with the values <em>requested</em>, <em>success</em> and <em>failure</em> (and again, I could probably use reselect or something alike for this).</p>

<p>I could then subscribe to the store in <code>onSubmit</code> and handle changes to <code>state.auth.status</code> like this:</p>

<pre><code>// ...

class LoginForm extends Component {
    constructor (props) {
        super(props)
        this.onSubmit = this.onSubmit.bind(this)
    }
    onSubmit (formData, dispatch) {
        const { store } = this.context
        return new Promise((resolve, reject) =&gt; {
            const unsubscribe = store.subscribe(() =&gt; {
                const state = store.getState()
                const status = state.auth.status

                if (status === 'success' || status === 'failure') {
                    unsubscribe()
                    status === 'success' ? resolve() : reject(state.auth.error)
                }
            })
            dispatch(login(formData))
        }).bind(this)
    }

    // ...
}
// ...
LoginForm.contextTypes = {
    store: PropTypes.object.isRequired
}

// ...
</code></pre>

<p>However, this solution doesn't feel good and I'm not sure if it will always work as expected when the app grows and more actions might be dispatched from other sources.</p>

<p>Another solution I have seen is moving the api call (which returns a promise) to <code>onSubmit</code>, but I would like to keep it seperated from the React component.</p>

<p>Any advice on this?</p>
