我正在使用React与后端进行通信。现在正在尝试正确地实现Formik(表单库)。
主要问题: 如何正确使用Formik的setError方法?
客户端验证错误已经正确显示,但现在我正在尝试设置/显示后端验证错误,这些错误是通过状态码400返回的响应中返回的。
链接到我正在尝试使用的方法的文档
我在以下代码中的名为handle400Error的方法中使用了这种方法。
我的React(和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>
);
}
setStatus
? API调用在saga中执行,如果出现错误,我会使用错误更新状态。我需要在useEffect中调用setStatus吗? - canecse