我正在使用 React 与后端通信。现在尝试正确实现 Formik(表单库)。
主要问题: 如何正确使用 Formik 的 setError 方法?
客户端验证错误正确显示,但现在我正在尝试设置/显示后端验证错误,这些错误返回状态码为 400 的响应。
链接到有关我尝试使用的方法的文档
我在下面的代码中名为handle400Error的方法中使用了这个方法。
我的反应(和 Formik)代码:
import React, { Component } from "react";
import axios from "axios";
import { Formik } from "formik";
import * as Yup from "yup";
import styled from "styled-components";
import FormError from "../formError";
const Label = styled.label``;
class LoginForm extends Component {
initialValues = {
password: "",
username: ""
};
getErrorsFromValidationError = validationError => {
const FIRST_ERROR = 0;
return validationError.inner.reduce((errors, error) => {
return {
...errors,
[error.path]: error.errors[FIRST_ERROR]
};
}, {});
};
getValidationSchema = values => {
return Yup.object().shape({
password: Yup.string()
.min(6, "Password must be at least 6 characters long")
.required("Password is required!"),
username: Yup.string()
.min(5, "Username must be at least 5 characters long")
.max(40, "Username can not be longer than 40 characters")
.required("Username is required")
});
};
handleSubmit = async (values, { setErrors }) => {
console.log("handleSubmit");
try {
const response = await axios.post(
"http://127.0.0.1:8000/rest-auth/login/",
values
);
const loginToken = response.data["key"];
this.handleLoginSuccess(loginToken);
} catch (exception) {
// Expected: 400 status code
if (exception.response && exception.response.status === 400) {
// Display server validation errors
this.handle400Error(exception.response.data, setErrors);
}
console.log("exception", exception);
console.log("exception.response", exception.response);
}
};
handle400Error = (backendErrors, setErrors) => {
let errors = {};
for (let key in backendErrors) {
errors[key] = backendErrors[key][0]; // for now only take the first error of the array
}
console.log("errors object", errors);
setErrors({ errors });
};
handleUnexpectedError = () => {};
handleLoginSuccess = loginToken => {
console.log("handleLoginSuccess");
this.props.setGreeneryAppState({
loginToken: loginToken
});
this.props.history.replace(`/${this.props.locale}/`);
};
validate = values => {
const validationSchema = this.getValidationSchema(values);
try {
validationSchema.validateSync(values, { abortEarly: false });
return {};
} catch (error) {
return this.getErrorsFromValidationError(error);
}
};
render() {
return (
<React.Fragment>
<h1>Login</h1>
<Formik
initialValues={this.initialValues}
validate={this.validate}
validationSchema={this.validationSchema}
onSubmit={this.handleSubmit}
render={({
errors,
touched,
values,
handleBlur,
handleChange,
handleSubmit
}) => (
<form onSubmit={handleSubmit}>
{errors.non_field_errors && (
<formError>{errors.non_field_errors}</formError>
)}
<Label>Username</Label>
<input
onChange={handleChange}
onBlur={handleBlur}
value={values.username}
type="text"
name="username"
placeholder="Enter username"
/>
{touched.username &&
errors.username && <FormError>{errors.username}</FormError>}
<Label>Password</Label>
<input
onChange={handleChange}
onBlur={handleBlur}
value={values.password}
type="password"
name="password"
placeholder="Enter password"
/>
{touched.password &&
errors.password && <FormError>{errors.password}</FormError>}
<button type="submit">Log in</button>
</form>
)}
/>
</React.Fragment>
);
}