在某些情况下,Formik 的标志“isValid”似乎被设置为
true
,即使表单值不应被视为有效。我在下面有一个工作代码和框示例,其中展示了这一点。
我用于表单的验证架构如下:
const validationSchema = Yup.object().shape(
{
heading: Yup.string().required('Heading required.'),
image: Yup.string().when('placeholder', {
is: '',
then: Yup.string().required(
'Please either choose an image, or a placeholder.'
),
otherwise: Yup.string(),
}),
placeholder: Yup.string().when('image', {
is: '',
then: Yup.string().required(
'Please either choose an image, or a placeholder.'
),
otherwise: Yup.string(),
}),
},
[['image', 'placeholder']]
);
输出Formik的
isValid
标志时,对于以下值是true
:
{ heading: 'a', image: '', placeholder: '' }
该模式规定“图像”或“占位符”字段中的一个必须存在,但在上面的情况下,它们不存在。然而 isValid
标志是
true
。当用 Yup 手动测试时,我得到了预期的结果:
validationSchema.validate(values).then(...).catch(...);
这可以在codesandbox中进一步看到。我在这里缺少什么?当 Formik 验证这些值时,幕后是否发生了更多事情?
formik.isValid
一起,我使用了另一个属性
formik.touched
,并且仅当formik.isValid = true
和Object.keys(formik.touched).length > 0
(至少某些字段应该是触动)如下:
const isFormValid = formik.isValid && Object.keys(formik.touched).length > 0; // WITH lodash: formik.isValid && !_.isEmpty(formik.touched)
if (isFormValid) {
// NOW SUBMIT THE FORM OR DO YOUR NEXT STEP
}
您需要将
validateOnMount
<Formik
validateOnMount={true}
initialValues={initialValues}
validationSchema={validationSchema}
>
// your form
</Formik>
当您使用
validateOnMount=true
不会触发验证。在 Formik v2 中,您可以在
validateForm()
之后调用 来重新运行验证。用途:
import { useRef } from "react";
const formRef = useRef();
const initialValues = { foo: "", bar: "" };
const appliedValues = { foo: "bar", bar: "foo" };
const someFunc = () => {
formRef.current.resetForm({ values: { ...initialValues, ...appliedValues} });
formRef.current.validateForm(); // note: this is a promise function, so call it at the end, or use .then() to chain with other formik functions.
};
<Formik
innerRef={formRef}
validateOnMount // <-- use this so it works for initial render
initialValues={initialValues}
...
>