#reactjs #typescript #formik #yup
Вопрос:
Я новичок во всех трех технологиях и искал ответ, но не смог его найти. Примечание: Я упростил файл, чтобы облегчить его анализ во время чтения, надеюсь, я не вырезал ничего важного для отладки.
Я хотел бы, чтобы моя форма регистрировалась как тронутая, когда пользователь нажимает, чтобы выбрать дату с помощью средства выбора календаря. В настоящее время я могу отобразить ошибку в тексте справки, но она не изменяет стиль формы так же, как это произойдет, если пользователь нажмет на поле, как если бы он намеревался ввести его сам.
import React, { FC, useRef } from "react";
import { Formik, Form, Field } from "formik";
import { KeyboardDatePicker } from "formik-material-ui-pickers";
import * as Yup from "yup";
import moment from "moment";
import { ReportConfig } from "../ReportConfig";
export type DProps = {
type: Type | null,
currentConfig: ReportConfig | null,
};
export const Dialog: FC<DProps> = ({ currentConfig }) => {
const form: any = useRef(null); // Reference to formik form
let initialValues = {
periodStart: moment(currentConfig?.periodStart),
periodEnd: moment(currentConfig?.periodEnd),
};
return (
<Formik
innerRef={form}
initialValues={initialValues}
validationSchema={Yup.object().shape({
periodStart: Yup.date()
.typeError("Enter a valid date.")
.max(Yup.ref("periodEnd"), "Must be before End.")
.required("Required"),
periodEnd: Yup.date()
.typeError("Enter a valid date.")
.min(Yup.ref("periodStart"), "Must be after Start.")
.required("Required"),
})}
>
{({ values, errors, touched, handleBlur }) => (
<Form>
<Field
variant="inline"
autoOk
name={"periodStart"}
value={values.periodStart}
label="Start Date"
inputVariant="outlined"
component={KeyboardDatePicker}
format="MM/DD/YYYY"
onBlur={handleBlur}
error={touched.periodEnd amp;amp; errors.periodStart !== undefined}
helperText={errors.periodStart}
/>
<Field
variant="inline"
autoOk
name={"periodEnd"}
value={values.periodEnd}
label="End Date"
inputVariant="outlined"
component={KeyboardDatePicker}
format="MM/DD/YYYY"
onBlur={handleBlur}
error={touched.periodEnd amp;amp; errors.periodEnd !== undefined}
helperText={errors.periodEnd}
/>
</Form>
)}
</Formik>
);
};
Ответ №1:
Я все понял. Вы должны добавить setFieldTouched и предоставить ему анонимную функцию, которая устанавливает значение true.
import React, { FC, useRef } from "react";
import { Formik, Form, Field } from "formik";
import { KeyboardDatePicker } from "formik-material-ui-pickers";
import * as Yup from "yup";
import moment from "moment";
import { ReportConfig } from "../ReportConfig";
export type DProps = {
type: Type | null,
currentConfig: ReportConfig | null,
};
export const Dialog: FC<DProps> = ({ currentConfig }) => {
const form: any = useRef(null); // Reference to formik form
let initialValues = {
periodStart: moment(currentConfig?.periodStart),
periodEnd: moment(currentConfig?.periodEnd),
};
return (
<Formik
innerRef={form}
initialValues={initialValues}
validationSchema={Yup.object().shape({
periodStart: Yup.date()
.typeError("Enter a valid date.")
.max(Yup.ref("periodEnd"), "Must be before End.")
.required("Required"),
periodEnd: Yup.date()
.typeError("Enter a valid date.")
.min(Yup.ref("periodStart"), "Must be after Start.")
.required("Required"),
})}
>
{({ values, errors, touched, handleBlur, setFieldTouched }) => (
<Form>
<Field
variant="inline"
autoOk
name={"periodStart"}
value={values.periodStart}
label="Start Date"
inputVariant="outlined"
component={KeyboardDatePicker}
format="MM/DD/YYYY"
onBlur={handleBlur}
error={touched.periodEnd amp;amp; errors.periodStart !== undefined}
helperText={errors.periodStart}
onClick={() => setFieldTouched("periodStart", true)}
/>
<Field
variant="inline"
autoOk
name={"periodEnd"}
value={values.periodEnd}
label="End Date"
inputVariant="outlined"
component={KeyboardDatePicker}
format="MM/DD/YYYY"
onBlur={handleBlur}
error={touched.periodEnd amp;amp; errors.periodEnd !== undefined}
helperText={errors.periodEnd}
onClick={() => setFieldTouched("periodEnd", true)}
/>
</Form>
)}
</Formik>
);
};