Validation 使用redux表单和fetchapi进行服务器验证

Validation 使用redux表单和fetchapi进行服务器验证,validation,redux,es6-promise,fetch-api,redux-form,Validation,Redux,Es6 Promise,Fetch Api,Redux Form,如何使用和获取API进行服务器端验证? 文档中提供了“”演示,其中说明执行服务器端验证的推荐方法是从onSubmit函数返回承诺。但是我应该把承诺放在哪里呢? 正如我所理解的,onSubmit函数应该是我的操作 <form onSubmit={this.props.addWidget}>... 如您所见,我使用fetchapi。我希望fetch将返回promise,redux表单将捕获它,但这不起作用。如何使它与来自的承诺一起工作 同样从演示中,我无法理解这个.props.hand

如何使用和获取API进行服务器端验证? 文档中提供了“”演示,其中说明执行服务器端验证的推荐方法是从onSubmit函数返回承诺。但是我应该把承诺放在哪里呢? 正如我所理解的,onSubmit函数应该是我的操作

<form onSubmit={this.props.addWidget}>...
如您所见,我使用fetchapi。我希望fetch将返回promise,redux表单将捕获它,但这不起作用。如何使它与来自的承诺一起工作


同样从演示中,我无法理解这个.props.handleSubmit函数应该提供什么。演示并没有解释这一部分,对我来说。

结果是
returnRejectedSubmitPromise
,它必须设置为true。

以下是我对使用fetch的看法,基于上的示例

  • …但我该把承诺放在哪里呢
  • …此.props.handleSubmit中应提供什么
详情见下文评论;很抱歉,代码块需要一些滚动才能读取:/


components/submitValidation.js
import React,{Component,PropTypes}来自'React';
从'redux form'导入{reduxForm};
从“../redux/modules/submission”导入{myHandleSubmit,显示为showResults};
类SubmitValidationForm扩展组件{
//以下三个道具都是由reduxForm()包装器/装饰器提供的
静态类型={
//我们在包装器中传递的字段名;
//每个字段现在都是具有以下属性的对象:
//价值、错误、触碰、弄脏等
//以及聚焦、模糊等方法
字段:PropTypes.object.isRequired,
//handleSubmit是如何处理提交:
//例如,防止默认、验证等
//不是什么构成成功或失败,而是由我们决定
//我必须向此表单传递提交函数,但我可以:
//a)在该组件中导入或定义函数(见上文),然后:
//```,或
//b)将该功能传递给该组件,如下所示:
//“那么
//   ``
handleSubmit:PropTypes.func.isRequired,
//redux表单侦听'reject({u error:'my error'})`,我们收到'this.props.error'`
错误:PropTypes.string
};
render(){
const{fields:{username,password},error,handleSubmit}=this.props;
返回(
{
//这可以理解为“如果触摸并出错,则渲染div”
username.toucted&&username.error&&{username.error}
}
{password.toucted&&password.error&&{password.error}
{
//这是一个通用错误,传递为{u error:'something'error}
错误&&{error}
}
//不确定为什么在示例中@erikras使用
//`onClick={handleSubmit}`这里..我怀疑是打字错误。
//因为我正在使用`type=“submit”`此按钮将在提交时触发
登录
);
}
}
//这是我提到的高阶组件
//作为包装器,它也可以写成@decorator
导出默认reduxForm({
表格:'提交验证',
字段:['username','password']//我们只在这里发送字段名
})(提交验证表);

。/redux/modules/submission.js
//(假设适当的导入)
函数postToApi(值){
返回fetch(API_端点{
凭据:“包括”,
模式:“cors”,
方法:“post”,
正文:JSON.stringify({values}),
标题:{
“内容类型”:“应用程序/json”,
“X-CSRFToken”:CSRF\U令牌
}
}).then(response=>Promise.all([response,response.json()]);
}
导出常量myHandleSubmit=(值,分派)=>{
调度(惊人的加载());
返回新承诺((解决、拒绝)=>{
//postToApi是fetch的包装器
postToApi(值)
。然后(([response,json])=>{
调度(停止加载());
//你的状态可能不同,我只关心202和400
如果(response.status==202){
调度(显示结果(值));
解决();
}
else if(response.status==400){
//在这里,我希望服务器将返回以下形状:
// {
//用户名:“用户不存在”,
//密码:“错误的密码”,
//_错误:“登录失败!”
// }
拒绝(json.errors);
}
否则{
//我们不确定发生了什么,但要处理好:
//我们的错误将直接传递给`.catch()`
抛出(新的错误(‘发生了可怕的错误’);
}
})
.catch(错误=>{
//否则未处理的服务器错误
调度(停止加载());
拒绝({u error:error});
});
});
};


如果我遗漏了什么/误解了什么等,请发表评论,我会修改:)

这个问题可能会有帮助:哦,我在想@memeLab中的例子是的,你是对的!谢谢你的帮助links@Denis你对此的最终解决方案是什么?我认为可能没有必要用另一个承诺来包装postToApi。。请参阅以获取示例。感谢您提供此解决方案。我有一个类似的问题,但是在实现您的解决方案时,我的代码正在运行到catch块中,即使API正在成功返回。catch块中返回的错误是
“TypeError:无法读取未定义(…)的属性'status'”
。我不确定这是从哪里来的redux表单。有没有关于我可能遗漏什么的想法?此外,对于您的上述评论,您是否建议编辑代码以删除
返回新承诺
片段?@geoboy,在fetch()包装中,您是否返回
。然后(response=>Promise.all([response,response.json()])
?注意,它将
[response,json]
传递给下一个。。如果您正在做一些明显不同的事情,那么这将解释未定义的错误(即
import fetch from 'isomorphic-fetch';
...
function fetchAddWidget(widget, workspace) {
    return dispatch => {
        dispatch(requestAddWidget(widget, workspace));
        return fetch.post(`/service/workspace/${workspace}/widget`, widget)
            .then(parseJSON)
            .then(json => {
                dispatch(successAddWidget(json, workspace));
                DataManager.handleSubscribes(json);
            })
            .catch(error => popupErrorMessages(error));
    }
}

export function addWidget(data, workspace) {
    return (dispatch, getState) => {
        return dispatch(fetchAddWidget(data, workspace));
    }
}