[英]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 在尝试提交时验证表单,如果有任何错误不允许提交表单,则由您在用户尝试提交错误时向用户显示错误消息,请参阅此页面以供参考
values
( which contains your form data) and handleChange
provided by formikvalues
(包含您的表单数据)和handleChange
将formik表单数据的值传递到输入字段onSubmit
as a prop where you can get your form state after validation and then, here you can register for your new user. onSubmit
作为道具,您可以在验证后获取您的表单 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.