【问题标题】:dispatch a action once server side validation passed in redux form一旦服务器端验证以 redux 形式通过,就调度一个动作
【发布时间】:2017-06-06 22:12:56
【问题描述】:

我在 redux 表单中遇到问题,我的问题在于代码,一旦我通过了服务器验证。我想发送一个动作,但我做不到, 我正在使用 redux 表单的 submit validations example 方法,在我的表单中我有客户端和服务器端验证。

LoginForm.js

import React from 'react'
import { Field, reduxForm } from 'redux-form'

import { required, email, maxLength25 } from '../utils/validations';
import validate from '../utils/signup_validate';
import { renderField } from '../utils/textFieldGroup';
import { login } from '../actions/submit';

const LoginForm =(props) => {
        const { handleSubmit, submitSucceeded, error } = props

        return (
          <form onSubmit={handleSubmit(login)}>
            <div className={typeof error!='undefined'?'show alert alert-danger': 'hidden'}>
             <strong>Error!</strong> {error}
            </div>
            <Field name="email" type="text"
              component={renderField} label="Email"
              validate={[ required, email, maxLength25 ]}
            />
            <Field name="password" type="password"
              component={renderField} label="Password"
              validate={[ required, maxLength25 ]}
            />
            <p>
              <button type="submit" disabled={submitSucceeded} className="btn btn-primary btn-lg">Submit</button>
            </p>
          </form>
        )
}

export default reduxForm({
  form: 'loginForm', // a unique identifier for this form
  validate
})(LoginForm)

提交.js

import axios from 'axios';
import isEmpty from 'lodash/isEmpty';
import { SubmissionError } from 'redux-form'
import {browserHistory} from 'react-router';
import setAuthorizationsToken from '../utils/setAuthorizationsToken';
import { SET_CURRENT_USER } from '../utils/types';
import jwt from 'jsonwebtoken';

export function login(data){
    console.log('submit', data);
    return axios.post('api/auth/login', data)
    .then((response) => {
        console.log('response', response.data.token);
        const token = response.data.token
        localStorage.setItem('jwtToken', token)
        setAuthorizationsToken(token)
        store.dispatch(setCurrentUser(jwt.decode(localStorage.jwtToken)))
        browserHistory.push('/');
    })
    .catch((error) => {
        console.log('error', error.response);
        throw new SubmissionError({ _error: error.response.data.errors});
    })
}

function setCurrentUser(user) {
    console.log('setCurrentUser');
    return {
        type: SET_CURRENT_USER,
        user: user
    }
}

我想调度 setCurrentUser 函数,以便我可以在 redux 存储中设置用户数据。

提前致谢。

【问题讨论】:

  • redux 是为状态管理而设计的,而不是为 API 调用而设计的。对于 API,最佳实践是使用 SUB/PUB 模式...尝试mufa,你会发现here 是一个反应样本+mufa
  • 为了管理 api 调用,我使用了 axios 库,我在更新 redux 存储时遇到了问题。感谢您的回复:)
  • 我可以帮你设置mufa.. 让我知道.. .skype: abdennour.tm .. 无论如何,文档here,示例here
  • 当然,谢谢哥们!

标签: redux react-redux redux-form redux-thunk react-router-redux


【解决方案1】:

解决方案 1

您可以传递另一个函数,而不是将您的登录函数直接传递给handleSubmit

login(data).then((user) => dispatch(setCurrentUser(user))

为此,您需要使用react-redux 中的connect 来允许您的组件访问redux store 的dispatch 函数。此外,您需要从 ajax 调用的resolve 分支返回用户:

.then((response) => {
    console.log('response', response.data.token);
    const token = response.data.token
    localStorage.setItem('jwtToken', token)
    setAuthorizationsToken(token)
    return jwt.decode(localStorage.jwtToken));
})

另外,我的建议是将browserHistory.push('/') 调用移至组件(在调度setCurrentUser 操作之后)

解决方案 2

您实际上需要将操作链接在一起,登录 -> 然后 -> setCurrentUser。为此,您应该使用 redux 中间件。如果您在我建议从redux-thunk 开始之前没有使用过中间件:https://github.com/gaearon/redux-thunk。使用redux-thunk,您可以在动作创建者中使用dispatch 函数来调度多个动作。如果您想了解更多信息,请在下方发表评论,我会尝试扩展我的答案。

【讨论】:

  • 感谢@alex 的回复,是的,我已经使用了 redux-thunk,但我仍然无法从动作创建者发送动作。请解释更多。
  • 我假设通过使用 login(data).then((user) => dispatch(setCurrentUser(user)),你希望我使用 HOC。目前我正在使用我使用的 LoginPage 容器LoginForm 演示组件,如下所示。codepen.io/mglrahul/pen/apWLEa?editors=0010
  • @RahulMangal 您的容器组件看起来不错,为了使用解决方案 1,您需要将您的 setCurrentUser 映射到 mapDispatchToProps 中的道具并在 then() 的函数上调用它login
  • 我按照你说的做了,但是我出错了,请看一下代码。 codepen.io/mglrahul/pen/apWLEa?editors=0010
  • setCurrentUser 需要在 mapDispatchToProps 部分中,您需要从您的动作创建者文件中导入它并在地图对象中使用它(连接的第二个参数)。至于登录功能本身,似乎与redux没有任何关系,所以不需要通过connect进行dispatch或映射。只需在需要时调用它,并且当诺言履行时,您发送您的setCurrentUser。不幸的是,我没有时间写完整的 sn-p,只需写一行,我稍后会回来。
猜你喜欢
  • 2017-11-01
  • 2018-11-25
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2019-08-14
  • 1970-01-01
相关资源
最近更新 更多