渲染后如何在formik中触发验证?
How to trigger validation in formik after rendering?
我有一个关于 formik 的问题。基本上,我将有一个 table 列出所有有错误的表单的 ID。当用户单击表单的 Id 时,它将显示表单本身。要求是在呈现表单时也应显示错误。有谁知道如何用 Formik 做到这一点?此外,如果用户编辑字段,字段验证应该正常工作。
我把codesandbox link放在这里了。 https://codesandbox.io/s/pensive-brattain-yyls2。基本上我希望当表单出现时我应该看到错误,而不仅仅是当用户离开字段或更改它时。谢谢。
import { Formik, Field, Form } from "formik";
import { TextField } from "formik-material-ui";
class Post0 extends React.Component {
validateEmptyName(value) {
if (!value) {
return "Invalid Name";
}
}
render() {
return (
<div>
<Formik
initialValues={{
email: "",
animal: ""
}}
onSubmit={values => {
this.props.nextStep(values);
}}
render={({ values, isSubmitting }) => (
<Form>
<Field
name="email"
type="email"
value={values.email}
component={TextField}
variant="outlined"
validate={this.validateEmptyName}
/>
<Field
name="animal"
value={values.animal}
component={TextField}
variant="outlined"
/>
<button type="submit">Submit</button>
</Form>
)}
/>
</div>
);
}
}
我使用自定义输入组件制作了一个 basic demo 版本。 Formik 没有内置选项来执行此操作,因此不幸的是,您需要创建自己的字段组件以与 Formik 的道具集成,并绕过如果未触及表单则不会显示验证的逻辑。
const Input = ({ field, form }) => {
useEffect(() => {
form.validateForm();
}, []);
return (
<div>
<input
style={{
border: form.errors[field.name] ? "1px solid red" : "1px solid #ccc"
}}
name={field.name}
value={field.value}
onChange={field.onChange}
/>
{form.errors[field.name] && (
<span style={{ color: "red" }}>{form.errors[field.name]}</span>
)}
</div>
);
};
然后将其作为 component
道具传递给您的 <Field/>
。
Formik 确实提供了一个 isInitialValid
道具,您可以在主要 Formik 组件上将其设置为 false
,但是如果没有 [=15,您正在使用的库 TextFields 将不会显示任何内容=] 道具
2021 年更新:
使用validateOnMount
道具:
我使用 Yup 的 validateAtSync
function 完成此操作,同时从查询字符串填充我的表单的初始值。
function generateInitialValues(tabs: TabType[], router: any, validationSchema: any) {
const initialValues: { [key: string]: number | string } = {};
_.forEach(tabs, (tab: TabType) => {
_.forEach(tab.formFields, (f: FormField) => {
let isFieldValid;
try {
// https://github.com/jquense/yup#mixedvalidatesyncatpath-string-value-any-options-object-any
console.log('validation schema validateAt: ', validationSchema.validateSyncAt(f.id, router.query[f.id]));
isFieldValid = validationSchema.validateSyncAt(f.id, router.query[f.id]);
} catch (e) {
// do nothing on purpose to stop exception from being thrown
// TODO: Consider doing something here, such as recording a metric
}
initialValues[f.id] = isFieldValid ? router.query[f.id] : f.defaultValue;
})
});
return initialValues;
}
您可以使用 isInitialValid 或 initialErrors 来验证初始值。
查看他们的官方文档 here.
如果您还添加 initialTouched
,validateOnMount
可以工作,但是当它在提交后显示验证问题时它有限制(...或者更确切地说是错误),这不会导致不同的视图或组件。
我找到了非常优雅的解决方法,可以按预期工作。
const formikRef = React.useRef(null);
React.useEffect(() => formikRef.current.validateForm(), []);
return (
<Formik
innerRef={formikRef}
initialValues={props.customer}
initialTouched={mapObject(props.customer, true)}
onSubmit={values => {
.
.
.
我有一个关于 formik 的问题。基本上,我将有一个 table 列出所有有错误的表单的 ID。当用户单击表单的 Id 时,它将显示表单本身。要求是在呈现表单时也应显示错误。有谁知道如何用 Formik 做到这一点?此外,如果用户编辑字段,字段验证应该正常工作。
我把codesandbox link放在这里了。 https://codesandbox.io/s/pensive-brattain-yyls2。基本上我希望当表单出现时我应该看到错误,而不仅仅是当用户离开字段或更改它时。谢谢。
import { Formik, Field, Form } from "formik";
import { TextField } from "formik-material-ui";
class Post0 extends React.Component {
validateEmptyName(value) {
if (!value) {
return "Invalid Name";
}
}
render() {
return (
<div>
<Formik
initialValues={{
email: "",
animal: ""
}}
onSubmit={values => {
this.props.nextStep(values);
}}
render={({ values, isSubmitting }) => (
<Form>
<Field
name="email"
type="email"
value={values.email}
component={TextField}
variant="outlined"
validate={this.validateEmptyName}
/>
<Field
name="animal"
value={values.animal}
component={TextField}
variant="outlined"
/>
<button type="submit">Submit</button>
</Form>
)}
/>
</div>
);
} }
我使用自定义输入组件制作了一个 basic demo 版本。 Formik 没有内置选项来执行此操作,因此不幸的是,您需要创建自己的字段组件以与 Formik 的道具集成,并绕过如果未触及表单则不会显示验证的逻辑。
const Input = ({ field, form }) => {
useEffect(() => {
form.validateForm();
}, []);
return (
<div>
<input
style={{
border: form.errors[field.name] ? "1px solid red" : "1px solid #ccc"
}}
name={field.name}
value={field.value}
onChange={field.onChange}
/>
{form.errors[field.name] && (
<span style={{ color: "red" }}>{form.errors[field.name]}</span>
)}
</div>
);
};
然后将其作为 component
道具传递给您的 <Field/>
。
Formik 确实提供了一个 isInitialValid
道具,您可以在主要 Formik 组件上将其设置为 false
,但是如果没有 [=15,您正在使用的库 TextFields 将不会显示任何内容=] 道具
2021 年更新:
使用validateOnMount
道具:
我使用 Yup 的 validateAtSync
function 完成此操作,同时从查询字符串填充我的表单的初始值。
function generateInitialValues(tabs: TabType[], router: any, validationSchema: any) {
const initialValues: { [key: string]: number | string } = {};
_.forEach(tabs, (tab: TabType) => {
_.forEach(tab.formFields, (f: FormField) => {
let isFieldValid;
try {
// https://github.com/jquense/yup#mixedvalidatesyncatpath-string-value-any-options-object-any
console.log('validation schema validateAt: ', validationSchema.validateSyncAt(f.id, router.query[f.id]));
isFieldValid = validationSchema.validateSyncAt(f.id, router.query[f.id]);
} catch (e) {
// do nothing on purpose to stop exception from being thrown
// TODO: Consider doing something here, such as recording a metric
}
initialValues[f.id] = isFieldValid ? router.query[f.id] : f.defaultValue;
})
});
return initialValues;
}
您可以使用 isInitialValid 或 initialErrors 来验证初始值。 查看他们的官方文档 here.
initialTouched
,validateOnMount
可以工作,但是当它在提交后显示验证问题时它有限制(...或者更确切地说是错误),这不会导致不同的视图或组件。
我找到了非常优雅的解决方法,可以按预期工作。
const formikRef = React.useRef(null);
React.useEffect(() => formikRef.current.validateForm(), []);
return (
<Formik
innerRef={formikRef}
initialValues={props.customer}
initialTouched={mapObject(props.customer, true)}
onSubmit={values => {
.
.
.