一旦服务器端验证以 redux 形式通过,就调度一个动作

Posted

技术标签:

【中文标题】一旦服务器端验证以 redux 形式通过,就调度一个动作【英文标题】:dispatch a action once server side validation passed in redux form 【发布时间】: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 当然,谢谢哥们! 【参考方案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,只需写一行,我稍后会回来。

以上是关于一旦服务器端验证以 redux 形式通过,就调度一个动作的主要内容,如果未能解决你的问题,请参考以下文章

React/Redux - 在应用程序加载/初始化时调度操作

如何让我的服务器端 Joi 验证与 redux-form 一起正常工作?

WebSocket 服务器中的 Redux

Redux 面试题

在通过动作调度进行状态更新后,在 React 中使用 Redux 执行函数?

使用 Play 以 JSON 形式返回验证错误!框架