在 blur/change 和 'touched' 上分别显示 (1) 提交点击和 (2) 错误
Show errors both (1) on Submit click and (2) individually on blur/change with 'touched'
在 Formik 中,我需要在两种 情况下显示验证错误:
- 在 Change/Blur 上,当字段在表单上被触及时单独 -- 不是一次全部,在填写过程中
- 随时单击提交:此处,所有 错误应立即显示。
(1) 有效,但 (2) 无效。当我来到表单并单击“提交”按钮时,没有任何反应,也没有显示错误。只有在我触摸控件时才会显示错误。
我认为问题是为了满足(1),我的控件有
isInvalid={touched.startDate && errors.startDate}
但是当我立即点击提交时,控件还没有被触及,所以这个isInvalid
条件不成立。但我不能删除 touched.startDate
部分,否则, 所有 无效控件总是在填写表单时开始显示——即使是那些我没有接触过的控件。我需要在填写时保留我的 touched
要求,但还要在提交时显示所有错误。提交是必须立即显示所有错误的一种情况。是否可以在某处传递一些 submitClicked
变量来实现此目的?
<Formik enableReinitialize
validationSchema={schema}
onSubmit={ (values, { validate }) => {
alert(JSON.stringify(values, null, 2));
}}
initialValues={{}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form onSubmit={handleSubmit}>
...
{/* EXAMPLE */}
<Form.Control type="date"
name="expirationDate"
value={values.expirationDate}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={touched.expirationDate && errors.expirationDate}
</Form.Control>
</Form>
...
// Yup Schema used for form validation
const schema = yup.object().shape({
expirationDate: yup.date().required('Expiration Date is required'),
frequencyDays: yup.number().required('Frequency is required'),
interval: yup.string().required('Frequency interval is required'),
...
我认为您是对的,因为您可以检查字段是否 touched
,验证后不会呈现错误。我认为一个解决方法是在调用 onSubmit 处理程序后以编程方式将所有字段的状态设置为 touched=true
。
form.setTouched({...form.touched,[field.name]: true });
没有 codesandbox 可以使用,但类似这样的东西
<Formik enableReinitialize
validationSchema={schema}
onSubmit={ (values, { validate }) => {
// Set the form fields to touched programmatically
form.setTouched({...form.touched,[field.name]: true });
alert(JSON.stringify(values, null, 2));
}}
initialValues={{}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form onSubmit={handleSubmit}>
...
{/* EXAMPLE */}
<Form.Control type="date"
name="expirationDate"
value={values.expirationDate}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={touched.expirationDate && errors.expirationDate}
</Form.Control>
</Form>
由于很多人都在查看此线程,因此我们得出了以下结果。这是我们的 React Bootstrap 控件示例,在本例中是一个在 Formik 中调用 frequencyDays
的 Select。请注意以下几点:
isInvalid={(submitClicked && errors.frequencyDays) ||
(!submitClicked && touched.frequencyDays && errors.frequencyDays)}
这意味着 (1) 单击提交但存在错误,或者 (2) 未单击提交但触摸了此控件,但存在错误。
<Form.Control as="select"
id="dropdownFrequencyDays"
name="frequencyDays"
value={values.frequencyDays}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={(submitClicked && errors.frequencyDays) || (!submitClicked && touched.frequencyDays && errors.frequencyDays)}
SubmitClicked是一个变量,initialized/set如下:
// Shows whether the Submit button was clicked (used to show all form validation errors at once)
// initially FALSE
const [submitClicked, setSubmitClicked] = useState(false);
在提交按钮的 onClick 中设置:
<Button type="submit" disabled={isSubmitting}
onClick={() => {
setSubmitClicked(true); // We set it to TRUE in Submit's onClick
}}
variant="primary">Submit</Button>
如果您使用的是 Material UI,它与 React-Bootstrap 类似,它的控件上有一些 error
属性,类似于isInvalid
.
在 Formik 中,我需要在两种 情况下显示验证错误:
- 在 Change/Blur 上,当字段在表单上被触及时单独 -- 不是一次全部,在填写过程中
- 随时单击提交:此处,所有 错误应立即显示。
(1) 有效,但 (2) 无效。当我来到表单并单击“提交”按钮时,没有任何反应,也没有显示错误。只有在我触摸控件时才会显示错误。
我认为问题是为了满足(1),我的控件有
isInvalid={touched.startDate && errors.startDate}
但是当我立即点击提交时,控件还没有被触及,所以这个isInvalid
条件不成立。但我不能删除 touched.startDate
部分,否则, 所有 无效控件总是在填写表单时开始显示——即使是那些我没有接触过的控件。我需要在填写时保留我的 touched
要求,但还要在提交时显示所有错误。提交是必须立即显示所有错误的一种情况。是否可以在某处传递一些 submitClicked
变量来实现此目的?
<Formik enableReinitialize
validationSchema={schema}
onSubmit={ (values, { validate }) => {
alert(JSON.stringify(values, null, 2));
}}
initialValues={{}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form onSubmit={handleSubmit}>
...
{/* EXAMPLE */}
<Form.Control type="date"
name="expirationDate"
value={values.expirationDate}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={touched.expirationDate && errors.expirationDate}
</Form.Control>
</Form>
...
// Yup Schema used for form validation
const schema = yup.object().shape({
expirationDate: yup.date().required('Expiration Date is required'),
frequencyDays: yup.number().required('Frequency is required'),
interval: yup.string().required('Frequency interval is required'),
...
我认为您是对的,因为您可以检查字段是否 touched
,验证后不会呈现错误。我认为一个解决方法是在调用 onSubmit 处理程序后以编程方式将所有字段的状态设置为 touched=true
。
form.setTouched({...form.touched,[field.name]: true });
没有 codesandbox 可以使用,但类似这样的东西
<Formik enableReinitialize
validationSchema={schema}
onSubmit={ (values, { validate }) => {
// Set the form fields to touched programmatically
form.setTouched({...form.touched,[field.name]: true });
alert(JSON.stringify(values, null, 2));
}}
initialValues={{}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form onSubmit={handleSubmit}>
...
{/* EXAMPLE */}
<Form.Control type="date"
name="expirationDate"
value={values.expirationDate}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={touched.expirationDate && errors.expirationDate}
</Form.Control>
</Form>
由于很多人都在查看此线程,因此我们得出了以下结果。这是我们的 React Bootstrap 控件示例,在本例中是一个在 Formik 中调用 frequencyDays
的 Select。请注意以下几点:
isInvalid={(submitClicked && errors.frequencyDays) ||
(!submitClicked && touched.frequencyDays && errors.frequencyDays)}
这意味着 (1) 单击提交但存在错误,或者 (2) 未单击提交但触摸了此控件,但存在错误。
<Form.Control as="select"
id="dropdownFrequencyDays"
name="frequencyDays"
value={values.frequencyDays}
onChange={handleChange}
onBlur={handleBlur}
isInvalid={(submitClicked && errors.frequencyDays) || (!submitClicked && touched.frequencyDays && errors.frequencyDays)}
SubmitClicked是一个变量,initialized/set如下:
// Shows whether the Submit button was clicked (used to show all form validation errors at once)
// initially FALSE
const [submitClicked, setSubmitClicked] = useState(false);
在提交按钮的 onClick 中设置:
<Button type="submit" disabled={isSubmitting}
onClick={() => {
setSubmitClicked(true); // We set it to TRUE in Submit's onClick
}}
variant="primary">Submit</Button>
如果您使用的是 Material UI,它与 React-Bootstrap 类似,它的控件上有一些 error
属性,类似于isInvalid
.