将 MUI DatePicker 与 yup 和 react-hook-form 一起使用 - error prop 无法按预期工作
Using the MUI DatePicker with yup and react-hook-form - the error prop doesn't work as intended
我正在使用 yup、react-hook-form 和 MUI DatePicker/TextField 制作注册表单。我想要一个出生日期字段来检查用户是否年满 18 岁。错误消息正确显示,但错误状态的红色仅在输入为空时有效(年龄低于 18 岁时无效)。我正在控制台记录指示红色的“无效”值,它应该设置为 true。
这是一个沙盒link:
https://codesandbox.io/s/datepicker-yup-validation-8rod3?file=/src/App.js
这个解决方案是用 formik ,是的和 material datepicker 编写的:
import "./styles.css";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import DateTimePicker from "@mui/lab/DateTimePicker";
import * as Yup from "yup";
import { useFormik } from "formik";
import { Button, TextField } from "@mui/material";
import moment from "moment";
var y = new Date();
y.setFullYear(y.getFullYear() - 18);
const validationSchema = Yup.object().shape({
voyageNumber: Yup.number(),
voyageStartDate: Yup.date(),
voyageEndDate: Yup.date().when("voyageStartDate", (voyageStartDate, schema) =>
moment(voyageStartDate).isValid() ? schema.max(voyageStartDate) : schema
)
});
export default function App() {
const formik = useFormik({
initialValues: {
voyageStartDate: moment().add(-18, "years"),
voyageEndDate: null
},
validationSchema: validationSchema,
onSubmit: (values) => {
console.log(values);
}
});
return (
<div className="App">
<form autoComplete="off">
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DateTimePicker
renderInput={(props) => (
<TextField
variant="standard"
className="w-100"
name="voyageEndDate"
required
{...props}
error={
formik.touched?.voyageEndDate &&
!!formik.errors?.voyageEndDate
}
helperText={
formik.touched?.voyageEndDate && formik.errors?.voyageEndDate
}
/>
)}
name="voyageEndDate"
label="Voyage End"
value={formik.values?.voyageEndDate}
onChange={(newValue) => {
console.log(
moment(newValue).format("YYYY-MM-DD HH:mm:ss"),
moment(y).format("YYYY-MM-DD HH:mm:ss"),
formik.errors
);
formik.setFieldTouched("voyageEndDate");
formik.setFieldValue(
"voyageEndDate",
moment(newValue).format("YYYY-MM-DD HH:mm:ss")
);
}}
onKeyPress={() => formik.setFieldTouched("voyageEndDate")}
/>
</LocalizationProvider>
<div style={{ marginTop: "15px" }}>
<Button variant="contained" color="primary" type="submit">
Add Voyage
</Button>
</div>
</form>
</div>
);
}
您只需将 error
属性放在 {...params}
之后,如下所示:
<DatePicker
...
renderInput={(params) => (
<TextField
helperText={invalid ? error.message : null}
id="dateOfBirth"
variant="standard"
margin="dense"
fullWidth
color="primary"
autoComplete="bday"
{...params}
error={invalid}
/>
)}
/>
我正在使用 yup、react-hook-form 和 MUI DatePicker/TextField 制作注册表单。我想要一个出生日期字段来检查用户是否年满 18 岁。错误消息正确显示,但错误状态的红色仅在输入为空时有效(年龄低于 18 岁时无效)。我正在控制台记录指示红色的“无效”值,它应该设置为 true。
这是一个沙盒link: https://codesandbox.io/s/datepicker-yup-validation-8rod3?file=/src/App.js
这个解决方案是用 formik ,是的和 material datepicker 编写的:
import "./styles.css";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import DateTimePicker from "@mui/lab/DateTimePicker";
import * as Yup from "yup";
import { useFormik } from "formik";
import { Button, TextField } from "@mui/material";
import moment from "moment";
var y = new Date();
y.setFullYear(y.getFullYear() - 18);
const validationSchema = Yup.object().shape({
voyageNumber: Yup.number(),
voyageStartDate: Yup.date(),
voyageEndDate: Yup.date().when("voyageStartDate", (voyageStartDate, schema) =>
moment(voyageStartDate).isValid() ? schema.max(voyageStartDate) : schema
)
});
export default function App() {
const formik = useFormik({
initialValues: {
voyageStartDate: moment().add(-18, "years"),
voyageEndDate: null
},
validationSchema: validationSchema,
onSubmit: (values) => {
console.log(values);
}
});
return (
<div className="App">
<form autoComplete="off">
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DateTimePicker
renderInput={(props) => (
<TextField
variant="standard"
className="w-100"
name="voyageEndDate"
required
{...props}
error={
formik.touched?.voyageEndDate &&
!!formik.errors?.voyageEndDate
}
helperText={
formik.touched?.voyageEndDate && formik.errors?.voyageEndDate
}
/>
)}
name="voyageEndDate"
label="Voyage End"
value={formik.values?.voyageEndDate}
onChange={(newValue) => {
console.log(
moment(newValue).format("YYYY-MM-DD HH:mm:ss"),
moment(y).format("YYYY-MM-DD HH:mm:ss"),
formik.errors
);
formik.setFieldTouched("voyageEndDate");
formik.setFieldValue(
"voyageEndDate",
moment(newValue).format("YYYY-MM-DD HH:mm:ss")
);
}}
onKeyPress={() => formik.setFieldTouched("voyageEndDate")}
/>
</LocalizationProvider>
<div style={{ marginTop: "15px" }}>
<Button variant="contained" color="primary" type="submit">
Add Voyage
</Button>
</div>
</form>
</div>
);
}
您只需将 error
属性放在 {...params}
之后,如下所示:
<DatePicker
...
renderInput={(params) => (
<TextField
helperText={invalid ? error.message : null}
id="dateOfBirth"
variant="standard"
margin="dense"
fullWidth
color="primary"
autoComplete="bday"
{...params}
error={invalid}
/>
)}
/>