当前位置:  开发笔记 > 编程语言 > 正文

react/redux-form:如何从onSubmit返回promise?

如何解决《react/redux-form:如何从onSubmit返回promise?》经验,为你挑选了1个好方法。

我试图围绕redux,react-redux和redux-form进行包装.

我已经设置了一个商店并添加了redux-form的reducer.我的表单组件如下所示:

登录表格

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 (
            
) } } LoginForm.propTypes = { fields: PropTypes.object.isRequired, handleSubmit: PropTypes.func.isRequired, submitting: PropTypes.bool.isRequired } export default reduxForm({ form: 'login', fields })(LoginForm)

这可以按预期工作,在redux DevTools中,我可以看到如何在表单输入上更新商店,以及在提交表单时login动作创建者调度登录操作.

我将redux-thunk中间件添加到商店并设置用于登录的操作创建者,如异步操作的redux文档中所述:

authActions.js

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 => {
        // update app state: requesting login
        dispatch(requestLogin(credentials))

        // try to log in
        apiClient.login(credentials)
            .then(authToken => dispatch(loginSuccess(authToken)))
            .catch(error => dispatch(loginFailure(error)))
    }
}

同样,在redux DevTools中,我可以看到它按预期工作.当dispatch(login(formData))被称为onSubmit在LoginForm的,第一个LOGIN_REQUEST动作是出动,其次是LOGIN_SUCCESSLOGIN_FAILURE.LOGIN_REQUEST将一个属性添加state.auth.pending = true到店,LOGIN_SUCCESSLOGIN_FAILURE会删除该属性.(我知道这可能是我使用重新选择的东西,但是现在我想保持简单.

现在,在redux-form文档中,我读到我可以返回一个promise onSubmit以更新表单状态(submitting,error).但我不确定这样做的正确方法是什么.dispatch(login(formData))回报undefined.

我可以state.auth.pending在商店中用一个变量来交换标志,例如请求state.auth.status的值,成功失败(再次,我可能会使用重新选择或类似的东西).

然后我可以订阅商店onSubmit并处理这样的更改state.auth.status:

// ...

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) => {
            const unsubscribe = store.subscribe(() => {
                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
}

// ...

但是,这个解决方案感觉并不好,我不确定当应用程序增长并且可能从其他来源发送更多操作时它是否总是按预期工作.

我看到的另一个解决方案是将api调用(返回一个promise)移动到onSubmit,但我想将它与React组件分开.

有什么建议吗?



1> Michelle Til..:

dispatch(login(formData)) 回报 undefined

基于redux-thunk的文档:

内部函数的任何返回值都将作为其dispatch自身的返回值.

所以,你想要的东西

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

        // try to log in
        apiClient.login(credentials)
            .then(authToken => dispatch(loginSuccess(authToken)))
            .catch(error => dispatch(loginFailure(error)))

        return promiseOfSomeSort;
    }
}

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有