将 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>
  );
}

sandbox link

您只需将 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}
    />
  )}
/>