handleSubmit и значения, не распознаваемые в форме Formik - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь создать форму входа в систему с помощью formik. Я запутался в том, как запустить функцию handleSubmit для вызова API входа в систему для входа пользователя. Я продолжал вызывать handleSubmit внутри onSubmit, но он не распознает значения и handleSubmit внутри метода onSubmit в строках 10 и 11 в моей коде andbox в файле ValidatedLoginForm. js. Где мне точно вызвать handleSubmit и позволить пользователю войти на мой сайт?

мои коды и поле

мой код выглядит примерно так:

import React, { useState } from "react";
import { Formik } from "formik";
import TextField from "@material-ui/core/TextField";
import * as Yup from "yup";

const ValidatedLoginForm = props => (
  <Formik
    initialValues={{ email: "", password: "" }}
    onSubmit={values => {
      const handleSubmit = async event => {
        event.preventDefault();

        var body = {
          password: password,
          email: email
        };
        console.log(body);
        const options = {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Accept: "application/json"
          },
          body: JSON.stringify(body)
        };
        const url = "/api/authenticate";
        try {
          const response = await fetch(url, options);
          const text = await response.text();

          if (text === "redirect") {
            props.history.push(`/editor`);
          } else if (text === "verifyemail") {
            props.history.push(`/verifyOtp/${this.state.email}`);
          } else {
            console.log("login failed");
            window.alert("login failed");
          }
        } catch (error) {
          console.error(error);
        }
      };
    }}
    //********Using Yup for validation********/

    validationSchema={Yup.object().shape({
      email: Yup.string()
        .email()
        .required("Required"),
      password: Yup.string()
        .required("No password provided.")
        .min(8, "Password is too short - should be 8 chars minimum.")
        .matches(/(?=.*[0-9])/, "Password must contain a number.")
    })}
  >
    {props => {
      const {
        values,
        touched,
        errors,
        isSubmitting,
        handleChange,
        handleBlur,
        handleSubmit
      } = props;
      return (
        <>
          <form onSubmit={handleSubmit} noValidate>
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              id="email"
              value={values.email}
              label="Email Address"
              name="email"
              autoComplete="email"
              autoFocus
              onChange={handleChange}
              onBlur={handleBlur}
              className={errors.email && touched.email && "error"}
            />
            {errors.email && touched.email && (
              <div className="input-feedback">{errors.email}</div>
            )}
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              name="password"
              value={values.password}
              label="Password"
              type="password"
              id="password"
              onBlur={handleBlur}
              autoComplete="current-password"
              className={errors.password && touched.password && "error"}
              onChange={handleChange}
            />

            {errors.password && touched.password && (
              <div className="input-feedback">{errors.password}</div>
            )}
            <button type="submit" disabled={isSubmitting}>
              Login
            </button>
          </form>
        </>
      );
    }}
  </Formik>
);

export default ValidatedLoginForm;

1 Ответ

1 голос
/ 14 января 2020

В настоящее время вы создаете новую функцию в вашем коде onSubmit, которая никогда не вызывается. Функция values => { ... } вызывается при отправке формы, но в этой функции вы создаете handleSubmit и никогда не вызываете ее.

Если вы немного переместите создание handleSubmit, все становится проще. читать. Это будет что-то вроде

import React, { useState } from "react";
import { Formik } from "formik";
import TextField from "@material-ui/core/TextField";
import * as EmailValidator from "email-validator";
import * as Yup from "yup";

const ValidatedLoginForm = props => {
  // The function that handles the logic when submitting the form
  const handleSubmit = async values => {
    // This function received the values from the form
    // The line below extract the two fields from the values object.
    const { email, password } = values;
    var body = {
      password: password,
      email: email
    };
    console.log(body);
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };
    const url = "/api/authenticate";
    try {
      const response = await fetch(url, options);
      const text = await response.text();

      if (text === "redirect") {
        props.history.push(`/editor`);
      } else if (text === "verifyemail") {
        props.history.push(`/verifyOtp/${this.state.email}`);
      } else {
        console.log("login failed");
        window.alert("login failed");
      }
    } catch (error) {
      console.error(error);
    }
  };

  // Returning the part that should be rendered
  // Just set handleSubmit as the handler for the onSubmit call.
  return (
    <Formik
      initialValues={{ email: "", password: "" }}
      onSubmit={handleSubmit}
      //********Using Yup for validation********/

      validationSchema={Yup.object().shape({
        email: Yup.string()
          .email()
          .required("Required"),
        password: Yup.string()
          .required("No password provided.")
          .min(8, "Password is too short - should be 8 chars minimum.")
          .matches(/(?=.*[0-9])/, "Password must contain a number.")
      })}
    >
      {props => {
        const {
          values,
          touched,
          errors,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit
        } = props;
        return (
          <>
            <form onSubmit={handleSubmit} noValidate>
              <TextField
                variant="outlined"
                margin="normal"
                required
                fullWidth
                id="email"
                value={values.email}
                label="Email Address"
                name="email"
                autoComplete="email"
                autoFocus
                onChange={handleChange}
                onBlur={handleBlur}
                className={errors.email && touched.email && "error"}
              />
              {errors.email && touched.email && (
                <div className="input-feedback">{errors.email}</div>
              )}
              <TextField
                variant="outlined"
                margin="normal"
                required
                fullWidth
                name="password"
                value={values.password}
                label="Password"
                type="password"
                id="password"
                onBlur={handleBlur}
                autoComplete="current-password"
                className={errors.password && touched.password && "error"}
                onChange={handleChange}
              />

              {errors.password && touched.password && (
                <div className="input-feedback">{errors.password}</div>
              )}
              <button type="submit" disabled={isSubmitting}>
                Login
              </button>
            </form>
          </>
        );
      }}
    </Formik>
  );
};

export default ValidatedLoginForm;

Я бы также убрал validationSchema из вашего компонента. Облегчает чтение / понимание, и его не нужно каждый раз создавать заново.

...