[英]Formik Yup validation running before field is touched
I have a form that has a field items
, which stores an array of objects with the properties image
and name
.我有一个表单,它有一个字段
items
,它存储了一个带有属性image
和name
的对象数组。 The image
property accepts a file but is optional, the name
field is required. image
属性接受一个文件,但它是可选的, name
字段是必需的。
For some reason, when I touch the name field, the image field validation kicks in and it throws the error "Image is too large", which can be seen from formik's errors object.出于某种原因,当我触摸名称字段时,图像字段验证开始并抛出错误“图像太大”,这可以从 formik 的错误对象中看出。 I don't understand why this is happening.
我不明白为什么会这样。 Below is the code for the component and a codesandbox which you can view here https://codesandbox.io/s/new-fog-xs2wb?file=/src/components/form.js
下面是组件的代码和一个代码和框,你可以在这里查看https://codesandbox.io/s/new-fog-xs2wb?file=/src/components/form.js
import React from 'react';
import { Formik, Field, FieldArray } from 'formik';
import * as Yup from 'yup';
function MyForm(props) {
const FILE_SIZE = 5 * 1024 * 1024;
const SUPPORTED_FORMATS = ["image/jpg", "image/jpeg", "image/gif", "image/png"];
const validationSchema = Yup.object().shape({
items: Yup.array().of(Yup.object().shape({
image: Yup.mixed()
.test("fileSize", "Image is too large", (value) => value && value.size <= FILE_SIZE)
.test(
"fileFormat",
"Unsupported Format - We only allow images.",
(value) => value && SUPPORTED_FORMATS.includes(value.type)
),
name: Yup.string().required('Required')
}))
});
const initialValues = { items: [{
image: undefined,
name: ''
}]}
return (
<div className="container">
<Formik enableReinitialize={true}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (values, { setSubmitting, resetForm }) => {
setSubmitting(true);
console.log(values);
setSubmitting(false);
}}>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
setFieldValue,
}) => (
<form className="mt-3" onSubmit={handleSubmit}>
<FieldArray name="items">
{({ push, remove }) => (
<React.Fragment>
{values.items && values.items.length && values.items.map((item, index) => (
<div key={index}>
{/* <Field name={`items[${index}].image`} /> */}
<div className="form-group">
<label htmlFor="name">Name</label>
<input name={`items[${index}].name`} className="form-control" id="name" aria-describedby="nameHelp" onChange={handleChange} onBlur={handleBlur} />
<small id="nameHelp" className="form-text text-muted">Enter a descriptive name for the item.</small>
</div>
<button type="button" className="btn btn-danger mr-2 mb-2" onClick={() => remove(index)}>Remove</button>
</div>
))}
<button type="button" className="btn btn-secondary mr-2 mt-4" onClick={() => push({image: undefined, name: ''})}>Add</button>
<button type="submit" disabled={isSubmitting} className="btn btn-primary mt-4">Submit</button>
<pre className="mt-2">{JSON.stringify(errors, null, 2)}</pre>
</React.Fragment>
)}
</FieldArray>
</form>
)}
</Formik>
</div>)
}
export default MyForm;
How do I get this to work as desired?我如何让它按预期工作? Your help is greatly appreciated.
非常感谢您的帮助。
The function that you used inside the test method should return false to show the resp error msg .您在测试方法中使用的函数应返回 false 以显示响应错误 msg 。 Ref: https://github.com/jquense/yup#mixedtestoptions-object-schema
参考: https : //github.com/jquense/yup#mixedtestoptions-object-schema
So you should do !(value?.size > FILE_SIZE)
and所以你应该做
!(value?.size > FILE_SIZE)
和!(value && !SUPPORTED_FORMATS.includes(value.type))
to make it work! !(value && !SUPPORTED_FORMATS.includes(value.type))
使其工作!
Code updates:代码更新:
image: Yup.mixed()
.test(
"fileSize",
"Image is too large",
(value) => !(value?.size > FILE_SIZE)
)
.test(
"fileFormat",
"Unsupported Format - We only allow images.",
(value) => !(value && !SUPPORTED_FORMATS.includes(value.type))
),
Formik
provides many utilities for validation, you can use below combo for your purpose: Formik
提供了许多用于验证的实用程序,您可以根据需要使用以下组合:
validateOnChange={false} validateOnBlur={true}
This will fix your problem, if any case it will not work then remove validateOnBlur
这将解决您的问题,如果在任何情况下都不起作用,则删除
validateOnBlur
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.