我正在使用React,Formik和yup将数据提交到REST API。
我的React组件如下:
import React from "react";
import { render } from "react-dom";
import { Formik, Field, Form, ErrorMessage } from "formik";
import * as Yup from "yup";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
const ContactUsFormSchema = Yup.object().shape({
givenName: Yup.string()
.required("First name is required")
.max(50, "Your first name must be 2 to 50 characters")
.min(2, "Your first name must be 2 to 50 characters"),
surname: Yup.string()
.required("Your last name is required")
.max(50, "Your last name must be 2 to 50 characters")
.min(2, "Your last name must be 2 to 50 characters"),
email: Yup.string()
.email()
.required("EMail address is required")
.max(100, "Your email address can't be longer than 100 characters")
});
class Register extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<button
id="home"
onClick={() => this.loadHome()}
className="square-button"
>
Home
</button>
<h1>SpringBoot/React OAuth2 Registration Page</h1>
<Formik
initialValues={{
givenName: this.props.user.givenName,
surname: this.props.user.surname,
email: this.props.user.email,
mobile: this.props.user.mobile
}}
validationSchema={ContactUsFormSchema}
// on submit Formik will call this passing the values and actions; call the doSubmit method passing them and the form itself
// Passing the form itself allows an action to be performed after the API call returns
onSubmit={(values, actions) => this.doSubmit(values, actions, this)}
// the render method returns the actual form; note each field has a corresponding error field
render={({ errors, touched, isSubmitting }) => (
<Form>
First Name:
<Field type="text" name="givenName" />
<ErrorMessage name="givenName">
{errorMessage => <div className="error">{errorMessage}</div>}
</ErrorMessage>
Last Name:
<Field type="text" name="surname" />
<ErrorMessage name="surname">
{errorMessage => <div className="error">{errorMessage}</div>}
</ErrorMessage>
Email Address:
<Field type="text" name="email" />
<ErrorMessage name="email">
{errorMessage => <div className="error">{errorMessage}</div>}
</ErrorMessage>
Mobile:
<Field type="text" name="mobile" />
<ErrorMessage name="mobile">
{errorMessage => <div className="error">{errorMessage}</div>}
</ErrorMessage>
<p />
{this.props.result}
<button type="submit" disabled={isSubmitting}>
Register
</button>
</Form>
)}
/>
</div>
);
}
doSubmit = (values, actions, form) => {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://localhost:8080/register", true);
xmlhttp.setRequestHeader("Accept", "application/json");
xmlhttp.setRequestHeader("Authorization", window.sessionStorage.jwt);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.onreadystatechange = function() {
// Function called when the state changes.
if (xmlhttp.readyState === 4) {
actions.setSubmitting(false);
if (xmlhttp.status === 200) {
render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
} else if (xmlhttp.status === 400) {
actions.setErrors(JSON.parse(xmlhttp.responseText).errors);
}
}
};
xmlhttp.send(JSON.stringify(values));
};
}
export default Register;
API返回的JSON数据为
{
"errorCode": "Validation failed",
"errors": [
{
"errorMessage": "Phone numbers must consist of digits and spaces only with an optional + sign at the front",
"field": "mobile"
}
]
}
我真的非常陌生,更不用说React等JavaScript了,所以我对为什么错误没有按我期望的那样填充感到非常困惑,并希望得到任何人愿意提供的帮助。
答案 0 :(得分:0)
您的errors
数组(从API返回)不适合Formik的error
模型。您要传递的对象应将字段名称作为键,并将某些字符串作为值。例如:
{
givenName: 'First name is required',
email: "Your email address can't be longer than 100 characters"
}
在您的情况下,您可以通过以下方式将错误数组转换为对象:https://jsfiddle.net/Lg87jwpb/2/(提供了注释imperative way
作为替代方法,以更好地了解其完成方式)。