Search code examples
reactjsreduxmaterial-uiformikyup

React Formik submission


I have an authorization and validation form for registration. I need to to make my form available for click events at my button. At first i added the resetform function in order to notice how my form actually works but after each click nothing happens.

import { Button, TextField } from "@mui/material";
import * as yup from "yup";
import { Formik } from "formik";

export const RegistrationForm = () => {
  const validationSchema = yup.object().shape({
    name: yup
      .string()
      .typeError("Должно быть строкой")
      .required("Обязательно")
      .matches(/^[аА-яЯ\s]+$/, "Имя должно состоять из русских букв"),
    secondName: yup
      .string()
      .typeError("Должно быть строкой")
      .required("Обязательно")
      .matches(/^[аА-яЯ\s]+$/, "Фамилия должна состоять из русских букв"),
    login: yup
      .string()
      .typeError("Должно быть строкой")
      .required("Обязательно"),
    password: yup
      .string()
      .typeError("Должно быть строкой")
      .required("Обязательно"),
    confirmPassword: yup
      .string()
      .oneOf([yup.ref("password")], "Пароли не совпадают")
      .required("Обязательно"),
    email: yup.string().email("Введите верный email").required("Обязательно"),
    confirmEmail: yup
      .string()
      .email("Введите верный email")
      .oneOf([yup.ref("email")], "Email не совпадают")
      .required("Обязательно"),
  });

  return (
    <>
      <header>
        <div className="head-btns">
          <Button variant="outlined">Зарегистрироваться</Button>
          <Button variant="outlined">Авторизоваться</Button>
        </div>
      </header>
      <Formik
        initialValues={{
          name: "",
          secondName: "",
          login: "",
          password: "",
          confirmPassword: "",
          email: "",
          confirmEmail: "",
        }}
        validateOnBlur
        onSubmit={({ resetForm }) => resetForm()}
        validationSchema={validationSchema}
      >
        {({
          values,
          errors,
          touched,
          handleChange,
          handleBlur,
          handleSubmit,
          isValid,
          dirty,
        }) => (
          <div className="register">
            <TextField
              id="outlined-basic"
              label="Имя"
              variant="outlined"
              className="field"
              name={"name"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.name}
            />
            {touched.name && errors.name && (
              <p className={"error"}>{errors.name}</p>
            )}
            <TextField
              id="outlined-basic"
              label="Фамилия"
              variant="outlined"
              className="field"
              name={"secondName"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.secondName}
            />
            {touched.secondName && errors.secondName && (
              <p className={"error"}>{errors.secondName}</p>
            )}
            <TextField
              id="outlined-basic"
              label="Логин"
              variant="outlined"
              className="field"
              name={"login"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.login}
            />
            {touched.login && errors.login && (
              <p className={"error"}>{errors.login}</p>
            )}
            <TextField
              type="password"
              id="outlined-basic"
              label="Пароль"
              variant="outlined"
              className="field"
              name={"password"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.password}
            />
            {touched.password && errors.password && (
              <p className={"error"}>{errors.password}</p>
            )}
            <TextField
              type="password"
              id="outlined-basic"
              label="Подтвердите пароль"
              variant="outlined"
              className="field"
              name={"confirmPassword"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.confirmPassword}
            />
            {touched.confirmPassword && errors.confirmPassword && (
              <p className={"error"}>{errors.confirmPassword}</p>
            )}
            <TextField
              id="outlined-basic"
              label="Email"
              variant="outlined"
              className="field"
              name={"email"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.email}
            />
            {touched.email && errors.email && (
              <p className={"error"}>{errors.email}</p>
            )}
            <TextField
              id="outlined-basic"
              label="Подтвердите Email"
              variant="outlined"
              className="field"
              name={"confirmEmail"}
              onChange={handleChange}
              onBlur={handleBlur}
              value={values.confirmEmail}
            />
            {touched.confirmEmail && errors.confirmEmail && (
              <p className={"error"}>{errors.confirmEmail}</p>
            )}
            <Button
              onClick={handleSubmit}
              disabled={!isValid || !dirty}
              type="submit"
              variant="contained"
              className="btn"
            >
              Зарегистрироваться
            </Button>
          </div>
        )}
      </Formik>
    </>
  );
}; 

I clicked the button and nothing happens but it should reset all inputs after this action


Solution

  • The onSubmit prop given to the <Formik /> component should be like this:

      <Formik
        onSubmit={(values, { resetForm }) => resetForm()}
        validationSchema={validationSchema}
      >
      </Formik>
    

    Formik options are passed to the second parameter of the submit handler.

    And you don't need to explicitly give your Button onClick handler with type="submit" if you define your form in the HTML form tag.

      <Formik
        onSubmit={(values, { resetForm }) => resetForm()}
        validationSchema={validationSchema}
      >
        {({ handleSubmit }) => (
            <form onSubmit={handleSubmit>
              {/* your form */}
              <Button 
                type="submit" // giving type submit to a button enclosed in a form will automatically call handleSubmit method
              >
               Submit
              </Button>
            </form>
    
        )}
      </Formik>