如何正确使用Formik的setError方法?(反应库)

我正在使用React与后端通信。现在尝试正确实现Formik(表单库)。

主要问题:

客户端验证错误可以正确显示,但是现在我尝试设置/显示后端验证错误,这些错误将通过状态码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>

);

}

回答:

Formik作者在这里…

setError在v0.8.0中已弃用,并重命名为setStatus。您可以使用setErrors(errors)setStatus(whateverYouWant)handleSubmit函数中获得所需的行为,如下所示:

handleSubmit = async (values, { setErrors, resetForm }) => {

try {

// attempt API call

} catch(e) {

setErrors(transformMyApiErrors(e))

// or setStatus(transformMyApiErrors(e))

}

}

如果您使用setErrors,您的错误将被Formik的下一个validatevalidationSchema调用清除,这些错误可以由用户键入(更改事件)或模糊输入(模糊事件)触发。注意:这是假设您尚未手动设置validateOnChange和设置validateOnBlur道具false(它们是true默认设置)。

IMHO

setStatus实际上是理想的选择,因为它将错误消息放置在Formik状态的单独部分中。然后,您可以像这样决定如何/何时向最终用户显示此消息。

// status can be whatever you want

{!!status && <FormError>{status}</FormError>}

// or mix it up, maybe transform status to mimic errors shape and then ...

{touched.email && (!!errors.email && <FormError>{errors.email}</FormError>) || (!!status && <FormError>{status.email}</FormError>) }

请注意,的存在或价值对status阻止下次提交表单没有影响。如果验证失败, Formik仅中止提交过程。

以上是 如何正确使用Formik的setError方法?(反应库) 的全部内容, 来源链接: utcz.com/qa/422442.html

回到顶部