简体   繁体   English

无法将 MaterialUI Datepicker、Dayjs 与 useFormik 和 Yup 一起使用

[英]unable to use MaterialUI Datepicker,Dayjs with useFormik and Yup

I am using Material UI Date picker with day js,but the issue that arising again and again is,'when I select the date on calender,1st time it updates in textfield and then it is not working.And also having problem in Yup like when touched 1st time it gives error means works perfectly but when removing the date from text field and left the field blank it does not work.'我在 day js 中使用 Material UI 日期选择器,但一次又一次出现的问题是,'当我 select 日历上的日期时,第一次在文本字段中更新然后它不起作用。而且在 Yup 中也有问题,比如当第一次触摸时,它给出错误意味着完美工作,但当从文本字段中删除日期并将该字段留空时,它不起作用。

codesandbox Link: https://codesandbox.io/s/material-ui-datepicker-error-pdvt07 codesandbox链接: https://codesandbox.io/s/material-ui-datepicker-error-pdvt07

code:代码:

    import "./styles.css";
import React, { useState } from "react";
import {
  TextField,
  Container,
  Typography,
  Stack,
  Button,
  Box
} from "@mui/material";
import { Link } from "react-router-dom";
import { Helmet } from "react-helmet-async";
import { styled } from "@mui/material/styles";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { DesktopDatePicker } from "@mui/x-date-pickers/DesktopDatePicker";
import TodayIcon from "@mui/icons-material/Today";
import moment from "moment";
import dayjs from "dayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import InputAdornment from "@mui/material/InputAdornment";
import Autocomplete from "react-google-autocomplete";
import { useFormik } from "formik";
import * as Yup from "yup";
// import useResponsive from "../../hooks/useResponsive";

export default function App() {
  // const navigate = useNavigate();
  const validationSchema = Yup.object().shape({
    firstName: Yup.string().required("First Name is required"),
    lastName: Yup.string()
      // .length(3, 'Last Name must be greater than 3 characters')
      .required("Last Name is required"),
    email: Yup.string()
      .email("Invalid email")
      .required("Please enter your email"),
    mobile: Yup.string()
      .length(10, "Mobile Number must be 10 digit")
      .required("Mobile Number is required"),
    dob: Yup.string().required("Dob is required"),
    passingYear: Yup.string().required("Passing out year is required"),
    location: Yup.string().required("Location is required"),
    occupation: Yup.string().required("Occupation is required"),
    address: Yup.string().required("Addres is required")
  });
  const formik = useFormik({
    initialValues: {
      firstName: "",
      lastName: "",
      email: "",
      mobile: "",
      dob: "",
      passingYear: "",
      location: "",
      address: "",
      occupation: ""
    },
    validationSchema,
    onSubmit: (values) => {
      console.log(values);
      // navigate(`/verify-otp?email=${values.email}`, { replace: true });
    }
  });

  return (
    <div className="App">
      <form onSubmit={formik.handleSubmit}>
        <Stack direction={"column"} spacing={3}>
          <Box>
            <TextField
              sx={{
                width: "100%"
              }}
              id="outlined-firstName-input"
              label="First Name"
              name="firstName"
              type={"text"}
              onChange={formik.handleChange}
              value={formik.values.firstName}
              onBlur={formik.handleBlur}
              autoComplete="off"
            />
            {formik.touched.firstName && formik.errors.firstName && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.firstName}
              </p>
            )}
          </Box>

          <Box>
            <TextField
              sx={{
                width: "100%"
              }}
              id="outlined-lastName-input"
              label="Last Name"
              name="lastName"
              type={"text"}
              onChange={formik.handleChange}
              value={formik.values.lastName}
              onBlur={formik.handleBlur}
              autoComplete="off"
            />
            {formik.touched.lastName && formik.errors.lastName && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.lastName}
              </p>
            )}
          </Box>

          <Box>
            <TextField
              sx={{
                width: "100%"
              }}
              id="outlined-email-input"
              label="Email address"
              name="email"
              type={"email"}
              onChange={formik.handleChange}
              value={formik.values.email}
              onBlur={formik.handleBlur}
            />
            {formik.touched.email && formik.errors.email && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.email}
              </p>
            )}
          </Box>

          <Box>
            <TextField
              sx={{
                width: "100%"
              }}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">+91</InputAdornment>
                )
              }}
              id="outlined-mobile-input"
              label="Mobile Number"
              type="tel"
              name="mobile"
              onChange={formik.handleChange}
              value={formik.values.mobile}
              onBlur={formik.handleBlur}
              autoComplete="off"
            />
            {formik.touched.mobile && formik.errors.mobile && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.mobile}
              </p>
            )}
          </Box>

          <Box
            sx={{
              width: "100%"
            }}
          >
            <LocalizationProvider dateAdapter={AdapterDayjs}>
              <DesktopDatePicker
                label="Date of birth"
                inputFormat="DD/MM/YYYY"
                value={dayjs(formik.values?.dob).format("DD-MM-YYYY") || ""}
                onChange={(newValue) => {
                  formik.setFieldValue(
                    "dob",
                    dayjs(newValue).format("DD-MM-YYYY")
                  );
                  formik.setFieldTouched("dob", true);
                }}
                renderInput={(params) => (
                  <TextField
                    sx={{
                      width: "100%"
                    }}
                    {...params}
                    name="dob"
                    onBlur={formik.handleBlur}
                    error={formik.errors.dob && formik.touched.dob}
                  />
                )}
              />
            </LocalizationProvider>
            {formik.touched.dob && formik.errors.dob && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.dob}
              </p>
            )}
          </Box>

          <Box
            sx={{
              width: "100%"
            }}
          >
            <LocalizationProvider dateAdapter={AdapterDayjs}>
              <DatePicker
                views={["year"]}
                label="Passing year"
                maxDate={dayjs().subtract(1, "year")}
                value={formik.values.passingYear || ""}
                onBlur={formik.handleBlur}
                onChange={(newValue) => {
                  formik.setFieldValue("passingYear", newValue?.format("YYYY"));
                }}
                renderInput={(params) => (
                  <TextField
                    sx={{
                      width: "100%"
                    }}
                    {...params}
                    name="passingYear"
                    onBlur={formik.handleBlur}
                    error={
                      formik.errors.passingYear && formik.touched.passingYear
                    }
                  />
                )}
              />

              {formik.touched.passingYear && formik.errors.passingYear && (
                <p
                  style={{
                    color: "red",
                    marginTop: "5px",
                    marginBottom: "-15px"
                  }}
                >
                  {formik.errors.passingYear}
                </p>
              )}
            </LocalizationProvider>
          </Box>

          <Box>
            <TextField
              sx={{
                width: "100%"
              }}
              id="outlined-occupation-input"
              label="Occupation"
              name="occupation"
              type={"text"}
              onChange={formik.handleChange}
              value={formik.values.occupation}
              onBlur={formik.handleBlur}
              autoComplete="off"
            />
            {formik.touched.occupation && formik.errors.occupation && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.occupation}
              </p>
            )}
          </Box>

          <Box>
            <Autocomplete
              className="location"
              style={{
                width: "100%",
                paddingLeft: "13px",
                height: "8vh",
                border: "1px solid rgb(224,224,224)",
                borderRadius: "6px",
                fontSize: "17px",
                fontWeight: "500",
                color: "#212B36",
                backgroundColor: "#F9FAFB",
                "&:focus": {
                  borderWidth: "2px",
                  borderColor: "darken(#2f8f1f, 5%)",
                  fontSize: "20px"
                }
              }}
              apiKey={"AIzaSyABX4LTqTLQGg_b3jFOH8Z6_H5CDqn8tbc"}
              onPlaceSelected={(place) => {
                formik.setFieldValue("location", place?.formatted_address);
              }}
              types={["address"]}
              componentRestrictions={{ country: "us" }}
              name="location"
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            />
            {formik.touched.location && formik.errors.location && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.location}
              </p>
            )}
          </Box>

          <Box
            sx={{
              width: "100%"
            }}
          >
            <TextField
              sx={{
                width: "100%"
              }}
              id="outlined-password-input"
              label="Addres"
              name="address"
              value={formik.values.address}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
              type="text"
              multiline
              rows={4}
              maxRows={6}
              autoComplete="off"
            />
            {formik.touched.address && formik.errors.address && (
              <p
                style={{
                  color: "red",
                  marginTop: "5px",
                  marginBottom: "-15px"
                }}
              >
                {formik.errors.address}
              </p>
            )}
          </Box>

          <Box ml={"auto"}>
            <Button fullWidth size="large" type="submit" variant="contained">
              Sign Up
            </Button>
          </Box>
        </Stack>
      </form>
    </div>
  );
}

Thanks in advance.....提前致谢.....

you need to use dayjs format when trying to display the date.尝试显示日期时需要使用 dayjs 格式。 the date picker already formats the date for you in the textfield.日期选择器已经在文本字段中为您设置了日期格式。

 <DesktopDatePicker
                label="Date of birth"
                inputFormat="DD/MM/YYYY"
                value={formik.values?.dob}
                onChange={(newValue) => {
                  formik.setFieldValue(
                    "dob",
                    newValue
                  );
                  formik.setFieldTouched("dob", true);
                }}
                renderInput={(params) => (
                  <TextField
                    sx={{
                      width: "100%"
                    }}
                    {...params}
                    name="dob"
                    onBlur={formik.handleBlur}
                    error={formik.errors.dob && formik.touched.dob}
                  />
                )}
              />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM