简体   繁体   English

Formik / Yup 验证 React 注册表单

[英]Formik / Yup Validation for Register Form on React

I am learning react and I have decided to create a React Front End that connects to Express.js on back-end.我正在学习 React,我决定创建一个 React 前端,在后端连接到 Express.js。 At the moment, I am trying to add validation on my register/login forms.目前,我正在尝试在我的注册/登录 forms 上添加验证。 I dont really understand how the validation system is implemented.我真的不明白验证系统是如何实现的。 I've noticed that tutorials use functional components for Formik/Yup however, I am using a class based component.我注意到教程使用 Formik/Yup 的功能组件,但是,我使用的是基于 class 的组件。

My register page doesn't display anything when i try to render it.当我尝试渲染它时,我的注册页面不显示任何内容。 Of course, I must have implemented this incorrectly, I cant figure out what to do.当然,我一定是错误地实现了这个,我不知道该怎么做。 Thank you for help.谢谢你的帮助。

 import React, { Component } from "react"; import { register } from "./UserFunctions"; import { Formik, Field } from "formik"; import * as Yup from "yup"; // const validationSchema = yup.object().shape({ // first_name: yup.string // }) class Register extends Component { constructor() { super(); this.state = { first_name: "", last_name: "", email: "", password: "", errors: {}, }; this.onChange = this.onChange.bind(this); this.onSubmit = this.onSubmit.bind(this); } onChange(e) { this.setState({ [e.target.name]: e.target.value }); } onSubmit(e) { e.preventDefault(); //new user object const newUser = { first_name: this.state.first_name, last_name: this.state.last_name, email: this.state.email, password: this.state.password, }; //if register function succesful, redirect to login page register(newUser).then((res) => { this.props.history.push(`/login`); }); } render() { return ( <div className="container"> <div className="row"> <div className="col-md-6 mt-5 mx-auto"> <Formik initialValues={{ first_name: "", last_name: "", email: "", password: "", }} validationSchema={Yup.object().shape({ first_name: Yup.string().required("First Name is Required.").min(1, "First Name is Too Short."), last_name: Yup.string().required("Last Name is Required.").min(1, "Last Name is Too Short."), email: Yup.string().email().required("Email is 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 { touched, errors, isSubmitting, handleChange, handleBlur, handleSubmit, } = props; <form noValidate onSubmit={this.onSubmit}> <h1 className="h3 mb-3 font-weight-normal">Register</h1> <div className="form-group"> <label htmlFor="name">First name</label> <input type="text" className="form-control" name="first_name" placeholder="Enter your first name" value={this.state.first_name} onChange={this.onChange} /> {errors.first_name && touched.first_name && ( <div className="input-feedback">{errors.first_name}</div> )} </div> <div className="form-group"> <label htmlFor="name">Last name</label> <input type="text" className="form-control" name="last_name" placeholder="Enter your last name" value={this.state.last_name} onChange={this.onChange} /> {errors.last_name && touched.last_name && ( <div className="input-feedback">{errors.last_name}</div> )} </div> <div className="form-group"> <label htmlFor="email">Email address</label> <input type="email" className="form-control" name="email" placeholder="Enter email" value={this.state.email} onChange={this.onChange} /> {errors.email && touched.email && ( <div className="input-feedback">{errors.email}</div> )} </div> <div className="form-group"> <label htmlFor="password">Password</label> <input type="password" className="form-control" name="password" placeholder="Password" value={this.state.password} onChange={this.onChange} /> {errors.password && touched.password && ( <div className="input-feedback">{errors.password}</div> )} </div> <button type="submit" className="btn btn-lg btn-primary btn-block" > Register; </button> </form>; }} </Formik> </div> </div> </div> ); } } export default Register;

Formik validates the form when trying to submit, if there are any errors it doesn't allow the form to be submitted, it is upto you to display the error messages to the user when he tries to submit with errors see this page for reference Formik 在尝试提交时验证表单,如果有任何错误不允许提交表单,则由您在用户尝试提交错误时向用户显示错误消息,请参阅此页面以供参考

  1. First, you need not use state while using Form Libraries.首先,在使用表单库时不需要使用 state。 The main purpose of using Form libraries is to encapsulate the state and reduce the boilerplate.使用Form库的主要目的是封装state,减少样板。
  2. Formik , itself, is a container for your form state. Formik本身就是您的表单 state 的容器。
  3. Please Note:- you should pass the values of the formik form data into the input fields by using values ( which contains your form data) and handleChange provided by formik请注意:- 您应该使用 formik 提供的values (包含您的表单数据)和handleChangeformik表单数据的值传递到输入字段
  4. Formik takes onSubmit as a prop where you can get your form state after validation and then, here you can register for your new user. FormikonSubmit作为道具,您可以在验证后获取您的表单 state,然后在这里您可以注册新用户。

Also, you can check the codesandbox link here .此外,您可以在此处查看代码框链接

import React, { Component } from "react";
// import { register } from "./UserFunctions";
import { Formik } from "formik";
import * as Yup from "yup";

const schema = Yup.object().shape({
  first_name: Yup.string()
    .required("First Name is Required.")
    .min(1, "First Name is Too Short."),
  last_name: Yup.string()
    .required("Last Name is Required.")
    .min(1, "Last Name is Too Short."),
  email: Yup.string().email().required("Email is 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.")
});

class Register extends Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-6 mt-5 mx-auto">
            <Formik
              initialValues={{
                first_name: "",
                last_name: "",
                email: "",
                password: ""
              }}
              validationSchema={schema}
              // tell the formik to validate onBlur
              validateOnBlur
              onSubmit={(values) => {
                // here you have the access to the form data
                // values.first_name, values_last_name, values_email, values_password 
                //if register function succesful, redirect to login page
                // register(values).then((res) => {
                //   this.props.history.push(`/login`);
                // })
              }}
            >
              {(props) => {
                const {
                  touched,
                  errors,
                  handleSubmit,
                  values,
                  handleChange,
                  handleBlur,
                } = props;

                return (
                  <form noValidate onSubmit={handleSubmit}>
                    <h1 className="h3 mb-3 font-weight-normal">Register</h1>
                    <div className="form-group">
                      <label htmlFor="name">First name</label>
                      <input
                        type="text"
                        className="form-control"
                        name="first_name"
                        placeholder="Enter your first name"

                        value={values.first_name}
                        onChange={handleChange}
                        onBlur={handleBlur}
                      />
                      {errors.first_name && touched.first_name && (
                        <div className="input-feedback">
                          {errors.first_name}
                        </div>
                      )}
                    </div>
                    <div className="form-group">
                      <label htmlFor="name">Last name</label>
                      <input
                        type="text"
                        className="form-control"
                        name="last_name"
                        placeholder="Enter your last name"
                        value={values.last_name}
                        onChange={handleChange}
                        onBlur={handleBlur}
                      />
                      {errors.last_name && touched.last_name && (
                        <div className="input-feedback">{errors.last_name}</div>
                      )}
                    </div>
                    <div className="form-group">
                      <label htmlFor="email">Email address</label>
                      <input
                        type="email"
                        className="form-control"
                        name="email"
                        placeholder="Enter email"
                        value={values.email}
                        onChange={handleChange}
                        onBlur={handleBlur}
                      />
                      {errors.email && touched.email && (
                        <div className="input-feedback">{errors.email}</div>
                      )}
                    </div>
                    <div className="form-group">
                      <label htmlFor="password">Password</label>
                      <input
                        type="password"
                        className="form-control"
                        name="password"
                        placeholder="Password"
                        value={values.password}
                        onChange={handleChange}
                        onBlur={handleBlur}
                      />
                      {errors.password && touched.password && (
                        <div className="input-feedback">{errors.password}</div>
                      )}
                    </div>
                    <button
                      type="submit"
                      className="btn btn-lg btn-primary btn-block"
                    >
                      Register!
                    </button>
                  </form>
                );
              }}
            </Formik>
          </div>
        </div>
      </div>
    );
  }
}

export default Register;

That is your code with functional component and with fewer code lines, it's working as expected那是您的代码具有功能组件且代码行更少,它按预期工作

import React from "react";
import { useFormik } from "formik";
import { register } from "./UserFunctions";
import * as Yup from "yup";

const Register = ({ history }) => {
  const validationSchema = Yup.object().shape({
    first_name: Yup.string()
      .required("First Name is Required.")
      .min(1, "First Name is Too Short."),
    last_name: Yup.string()
      .required("Last Name is Required.")
      .min(1, "Last Name is Too Short."),
    email: Yup.string().email().required("Email is 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."),
  });

  const formik = useFormik({
    initialValues: {
      first_name: "",
      last_name: "",
      email: "",
      password: "",
    },

    validationSchema: validationSchema,

    onSubmit: (values) => {
      const newUser = {
        first_name: values.first_name,
        last_name: values.last_name,
        email: values.email,
        password: values.password,
      };

      //if register function succesful, redirect to login page
      register(newUser).then((res) => {
        history.push(`/login`);
      });
    },
  });

  return (
    <div className="container">
      <div className="row">
        <div className="col-md-6 mt-5 mx-auto">
          <form noValidate onSubmit={formik.handleSubmit}>
            <h1 className="h3 mb-3 font-weight-normal">Register</h1>
            <div className="form-group">
              <label htmlFor="name">First name</label>
              <input
                type="text"
                className="form-control"
                name="first_name"
                placeholder="Enter your first name"
                value={formik.values.first_name}
                onChange={formik.handleChange}
              />
              {formik.errors.first_name && formik.touched.first_name && (
                <div className="input-feedback">{formik.errors.first_name}</div>
              )}
            </div>
            <div className="form-group">
              <label htmlFor="name">Last name</label>
              <input
                type="text"
                className="form-control"
                name="last_name"
                placeholder="Enter your last name"
                value={formik.values.last_name}
                onChange={formik.handleChange}
              />
              {formik.errors.last_name && formik.touched.last_name && (
                <div className="input-feedback">{formik.errors.last_name}</div>
              )}
            </div>
            <div className="form-group">
              <label htmlFor="email">Email address</label>
              <input
                type="email"
                className="form-control"
                name="email"
                placeholder="Enter email"
                value={formik.values.email}
                onChange={formik.handleChange}
              />
              {formik.errors.email && formik.touched.email && (
                <div className="input-feedback">{formik.errors.email}</div>
              )}
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input
                type="password"
                className="form-control"
                name="password"
                placeholder="Password"
                value={formik.values.password}
                onChange={formik.handleChange}
              />
              {formik.errors.password && formik.touched.password && (
                <div className="input-feedback">{formik.errors.password}</div>
              )}
            </div>
            <button type="submit" className="btn btn-lg btn-primary btn-block">
              Register!
            </button>
          </form>
          ;
        </div>
      </div>
    </div>
  );
};

export default Register;

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

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