Javascript 如何在React表单提交处理程序中正确捕获和分析错误?
我使用的是React 16.13.0。我有以下功能来处理提交事件:Javascript 如何在React表单提交处理程序中正确捕获和分析错误?,javascript,reactjs,error-handling,fetch-api,Javascript,Reactjs,Error Handling,Fetch Api,我使用的是React 16.13.0。我有以下功能来处理提交事件: handleFormSubmit(e) { e.preventDefault(); const NC = this.state.newCoop; delete NC.address.country; fetch('/coops/',{ method: "POST", body: JSON.stringify(this.state.newCoop), headers: {
handleFormSubmit(e) {
e.preventDefault();
const NC = this.state.newCoop;
delete NC.address.country;
fetch('/coops/',{
method: "POST",
body: JSON.stringify(this.state.newCoop),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
}).then(response => {
if (response.ok) {
return response.json();
}
console.log(response.json());
console.log(response.body);
throw new Error(response.statusText);
}).catch(errors => {
console.log(errors);
this.setState({ errors });
});
}
但是,我在从响应中正确获取错误时遇到了一个问题。当发生错误时,我的端点返回一个包含错误文本的400请求。这就是curl中发生的情况:
curl --header "Content-type: application/json" --data "$req" --request POST "http://localhost:9090/coops/"
{"phone":["The phone number entered is not valid."]}
但是response.statusText
包含“400(错误请求)”。捕获错误文本并将其保留以供将来解析的正确方法是什么?如果我的端点需要以不同的方式格式化数据,它应该做什么(使用Django/Python3.7)
编辑:
这是我试图在其中显示错误的输入组件:
<Input inputType={'text'}
title = {'Phone'}
name = {'phone'}
value = {this.state.newCoop.phone}
placeholder = {'Enter phone number'}
handleChange = {this.handleInput}
errors = {this.state.errors}
/>
当我运行console.log(错误)
时,它们如下所示:
{phone: Array(1), web_site: Array(1)}
实际上,
fetch
API与其他API有些不同。您应该传递另一个.then()
来获取数据,然后对其进行分析,使用几个回调使代码难以读取,我使用async/await
来处理错误:
async handleFormSubmit(e) {
e.preventDefault();
const NC = this.state.newCoop;
delete NC.address.country;
try {
const response = await fetch('/coops/',{
method: "POST",
body: JSON.stringify(this.state.newCoop),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
});
if (response.ok) {
const result = await response.json();
console.log('_result_: ', result);
return result;
}
throw await response.json();
} catch (errors) {
console.log('_error_: ', errors);
this.setState({ errors });
}
}
更新您的新问题:
当然,这是另一个问题,为什么错误没有出现,事实上,电话
错误是和JavaScript数组,您应该通过下面的方式显示它,代码,我使用重构分配作为道具:
import React from 'react';
import { FormControl, FormLabel } from 'react-bootstrap';
const Input = ({
title,
type,
name,
value,
placeholder,
handleChange,
errors,
}) => (
<div className="form-group">
<FormLabel>{title}</FormLabel>
<FormControl
type={type}
id={name}
name={name}
value={value}
placeholder={placeholder}
onChange={handleChange}
/>
{errors && errors[name] && (
<FormControl.Feedback>
{errors[name].map((err, i) => (
<div key={err+i} className="fieldError">{err}</div>
))}
</FormControl.Feedback>
)}
</div>
);
export default Input;
从“React”导入React;
从“react bootstrap”导入{FormControl,FormLabel};
常量输入=({
标题
类型,
名称
价值
占位符,
handleChange,
错误,
}) => (
{title}
{errors&&errors[name]&&(
{errors[name].map((err,i)=>(
{err}
))}
)}
);
导出默认输入;
您并没有真正解释如何处理响应。但是根据您对抛出新错误的使用情况,我假设您需要以下.catch
调用来处理它。在下面的解决方案中,errors
将从JSON响应中分配对象
response.json()
返回承诺。如果要将该值作为错误“抛出”,则必须执行以下操作(而不是抛出新错误(…)
):
从回调返回被拒绝的承诺。然后
回调将导致所述调用返回的承诺也被拒绝
在这方面:
fetch('/coops/',{
method: "POST",
body: JSON.stringify(this.state.newCoop),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
}).then(response => {
if (response.ok) {
return response.json();
}
return response.json().then(x => Promise.reject(x));
}).catch(errors => {
console.log(errors);
this.setState({ errors });
});
注意:由于您没有使用成功响应的返回值执行任何操作,因此不需要使用if
语句中的return response.json()
。您可以将该调用重写为:
.then(response => {
if (!response.ok) {
return response.json().then(x => Promise.reject(x));
}
})
如果我的端点需要以不同的方式格式化数据,它应该做什么(使用Django/Python3.7)
由于我们不知道您的组件需要什么样的结构,因此我们无法提供太多建议 属性API声明:
只读
一个布尔值,指示响应是否成功(状态为
范围为200–299)
这意味着即使response.ok
为false,response.json()
也将返回数据
获取一个流并将其读取到完成。它返回一个
使用解析正文文本的结果解析为
因此,在代码中,您应该将第一次获取解析定义为异步,如果响应不是ok
,则使用wait
,使用解析的response.json()
抛出:
handleFormSubmit(e){
e、 预防默认值();
const NC=this.state.newCoop;
删除NC.address.country;
获取(“/coops/”{
方法:“张贴”,
正文:JSON.stringify(this.state.newCoop),
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
}).then(async response=>{//定义异步函数的第一个解析
if(response.ok){
//如果可以,解析JSON并返回实际数据
return wait response.json();
//或者最好设置反应状态
//const data=wait response.json();
//this.setState({data});
}否则{
//不正常,在JSON数据中抛出一个错误
//这样你就能抓住
抛出wait response.json();
}
}).catch(错误=>{
//这里您应该得到JSON响应的实际错误
console.log(错误);
this.setState({errors});
});
}
您可以在此检查正在使用的测试示例
如果我的端点需要以不同的方式格式化数据,它应该做什么
(使用Django/Python 3.7)
您必须通过提供一些代码和解释,让我们更多地了解端点如何处理请求
更新
关于组件和显示错误,结果JSON为每个字段返回一个错误数组。如果只显示一个错误,则将端点更改为返回字符串而不是数组,或者仅显示第一个错误。如果有多个错误,则可以通过每个字段的“所有错误”数组进行映射和渲染:
const输入=(道具)=>{
返回(
{props.title}
//如果只想显示第一个错误
//然后渲染errors数组的第一个元素
{props.errors&&props.errors[props.name]&&(
{props.errors[props.name][0]}
)}
//或者如果每个字段都有多个错误
//然后映射并渲染所有错误
{/*
{props.errors&&props.errors[props.name]&&(
{props.errors[props.name].map((错误,索引)=>(
{错误}
))}
)}
*/}
)
}
让catch部分捕获失败错误,然后在then部分捕获您需要的错误
}).then(response => {
//use a switch to got through the responses or an if statement
var response = JSON.Parse(response)
//here am assuming after you console log response you gt the correct array placement
if(response[0]==200){
// this indicates success
return JSON.stringify({"success":"true","message":"success message";})
}else if(response[0]==400){
// this indicates error
return JSON.stringify({"success":"false","message":"Error message";})
}
}).catch(errors => {
console.log(errors);
this.setState({ errors });
});
另一方面,您可以检查数组中的第一个条目,以确定查询是否成功
.then(response => {
if (!response.ok) {
return response.json().then(x => Promise.reject(x));
}
})
}).then(response => {
//use a switch to got through the responses or an if statement
var response = JSON.Parse(response)
//here am assuming after you console log response you gt the correct array placement
if(response[0]==200){
// this indicates success
return JSON.stringify({"success":"true","message":"success message";})
}else if(response[0]==400){
// this indicates error
return JSON.stringify({"success":"false","message":"Error message";})
}
}).catch(errors => {
console.log(errors);
this.setState({ errors });
});