Contents
Setup Project React
Sử dụng Create React App to để tạo project. Đối với bài viết này, mình sẽ đặt tên project là validate-react-login-form.
npx create-react-app validate-react-login-form
Bạn vào thư mục project, sau đó start và xem kết quả trên browser
cd validate-react-login-form
npm start
Với mục đích của hướng dẫn này, bạn sẽ tạo app React và thao tác với ba tệp: index.js, index.css và ValidatedLoginForm.js.
Cài đặt Formik
Bây giờ chúng ta tạo dự án ban đầu của mình, chúng ta sẽ cài đặt ba packages: Formik, email-validator và Yup.
Formik giúp xử lý xác thực, thông báo lỗi và gửi biểu mẫu dễ quản lý hơn.
Cài đặt Formik như sau
npm install formik
email-validator là package được sử dụng để xác nhận email.
Cài đặt email-validator
:
npm install email-validator
Yup là một trình xác nhận schema thường được sử dụng cùng với Formik.
npm install yup
Chúng ta đã cài đặt xong những package cần thiết cho app React, tiếp theo tạo from validate component nào
Tạo Validated Form Component
Bây giờ chúng ta tạo những thứ cơ bản nhất và import vào thư mục gốc để hiển thị.
Để làm được như vậy, chúng ta thực hiện những bước sau
- Tạo một function component mới
- Thêm dữ liệu hiển thị vào
- Import chúng vào file
index.js
Tạo file bên trong src
và đặt tên ValidatedLoginForm.js
. Bên trong file đó thêm hàm như sau component:src/ValidatedLoginForm.js
import React from "react";
const ValidatedLoginForm = () => (
<div>
<h1>Validated Form Component</h1>
</div>
);
export default ValidatedLoginForm;
Chúng ta import vào file index.js
file:src/index.js
import ValidatedLoginForm from "./ValidatedLoginForm";
Chúng ta tiếp tục tạo form
<ValidatedLoginForm />
Khi bạn import tất cả vào với nhau, index.js sẽ trông như thế này:
import React from "react";
import ReactDOM from "react-dom";
import ValidatedLoginForm from "./ValidatedLoginForm";
function App() {
return (
<div className="App">
<h1>Validated Login Form</h1>
<ValidatedLoginForm />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Bạn sẽ thấy form component hiển thị như sau:

Bây giờ, chúng ta vào ValidatedLoginForm.js
và thêm Formik.
Đầu tiên import Formik, email-validator, và Yup
import { Formik } from "formik";
import * as EmailValidator from "email-validator"; // used when validating with a self-implemented approach
import * as Yup from "yup"; // used when validating with a pre-built solution
Bây giờ, hãy viết tag Formik với các giá trị ban đầu. Hãy nghĩ về các giá trị ban đầu và thiết lập state.
Bạn cũng sẽ cần callback onSubmit. Callback sẽ lấy hai tham số, giá trị và một đối tượng. Các giá trị biểu hiện cho các giá trị đầu vào từ form của bạn. Bạn sẽ thêm một số mã giả ở đây để mô phỏng callback đăng nhập không đồng bộ, sau đó đăng xuất
Trong callback, hãy gọi hàm setSubmmit đã bị hủy từ các tham số thứ hai. Điều này sẽ cho phép bạn bật hoặc tắt button Submit trong khi call login không đồng bộ đang diễn ra:
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log("Logging in", values);
setSubmitting(false);
}, 500);
}}
>
<h1>Validated Login Form</h1>
</Formik>
Render Props
Component Formik sử dụng render props để cung cấp các biến và hàm nhất định cho form mà chúng ta tạo.
Nói tóm lại, render props được sử dụng để chuyển các thuộc tính cho các phần tử con của một component. Trong trường hợp này, Formik sẽ chuyển các thuộc tính cho biểu mẫu của bạn.
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<div>
<h1>Validated Login Form</h1>
</div>
);
}}
Thêm code vào trong ứng dụng React
import React from "react";
import { Formik } from "formik";
import * as EmailValidator from "email-validator";
import * as Yup from "yup";
const ValidatedLoginForm = () => (
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log("Logging in", values);
setSubmitting(false);
}, 500);
}}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<div>
<h1>Validated Login Form</h1>
</div>
);
}}
</Formik>
);
export default ValidatedLoginForm;
Hiển thị Form
Bây giờ bạn có thể bắt đầu viết mã để hiển thị form. Form có hai đầu vào (email và mật khẩu), nhãn cho buttn Submit
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
/>
<label htmlFor="password">Password</label>
<input
id="password"
name="password"
type="password"
placeholder="Enter your password"
/>
<button type="submit">
Login
</button>
</form>
);
}}
onSubmit gọi từ handleSubmit từ props
<button type="submit" disabled={isSubmitting}>
Login
</button>
Bạn tùy chỉnh CSS cho file styles.css như bên dưới
.App {
font-family: sans-serif;
}
h1 {
text-align: center;
}
form {
max-width: 500px;
width: 100%;
margin: 0 auto;
}
label,
input {
display: block;
width: 100%;
}
label {
margin-bottom: 5px;
height: 22px;
}
input {
margin-bottom: 20px;
padding: 10px;
border-radius: 3px;
border: 1px solid #777;
}
input.error {
border-color: red;
}
.input-feedback {
color: rgb(235, 54, 54);
margin-top: -15px;
font-size: 14px;
margin-bottom: 20px;
}
button {
padding: 10px 15px;
background-color: rgb(70, 153, 179);
color: white;
border: 1px solid rgb(70, 153, 179);
transition: ease-in-out background-color 250ms, ease-in-out color 250ms;
}
button:hover {
cursor: pointer;
background-color: white;
color: rgb(70, 153, 179);
}
Sau đó bạn import style.css vào index. Js
import "./styles.css";
Thêm message vào Validation
Bây giờ, chúng ta sẽ tạo validate input. Đầu tiên xác định điều chúng ta muốn. Với Email, nên được như sau
- Phải được nhập
- Nhìn như email thật
Đối với password
- Cũng phải được nhập
- Phải có ít nhất 8 kí tự
- Trong đó chứa ít nhất 1 kí tự số
Chúng ta sẽ tạo ra message theo 2 cách, 1 bằng cách thủ công và 1 bằng cách sử dụng Yup
Tạo message
Đầu tiên chúng ta tạo hàm để validate. Kiểm tra dữ liệu được nhập từ form và trả về object errors có 2 giá trị chính là value và message
Bên trong tag Formik, chúng ta thêm code vào như sau
validate={values => {
let errors = {};
errors.email = "Invalid email";
return errors;
}}
Bây giờ chúng ta thêm Required để chắc rằng form được nhập bất cứ thứ gì
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
}
return errors;
}}
Sau đó sử dụng email-validator để kiểm email có định dạng như email thật.
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
} else if (!EmailValidator.validate(values.email)) {
errors.email = "Invalid email address.";
}
return errors;
}}
Bạn cũng cần check password như email
validate={values => {
let errors = {};
if (!values.password) {
errors.password = "Required";
}
return errors;
}}
Chúng ta check ít nhất 8 kí tự theo đoạn code sau
validate={values => {
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
}
return errors;
}}
Cuối cùng, check password với ít nhất 1 ký tự bằng cách sử dụng regex
validate={values => {
let errors = {};
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
} else if (!passwordRegex.test(values.password)) {
errors.password = "Invalid password. Must contain one number.";
}
return errors;
}}
Toàn bộ đoạn code phần check validate như sau
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
} else if (!EmailValidator.validate(values.email)) {
errors.email = "Invalid email address.";
}
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
} else if (!passwordRegex.test(values.password)) {
errors.password = "Invalid password. Must contain one number.";
}
return errors;
}}
Password Validation
Chúng ta sử dụng validationSchema của Yup để check như sau
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required("Required")
})}
Đối với password code như sau
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.")
})}
Hãy cùng khám phá sự khác biệt giữa 2 phương thức ngay nào
Hiển thị Validation và Error Messages
Hiện tại, chúng ta đã có logic cho message, việc cần làm là hiển thị chúng. Bạn cần update các thuộc tính input trong form như sau
Chúng ta cần update một số thuộc tính cho email và password như sa
value
onChange
onBlur
className
Render Props trong field Email
Chúng ta bắt đầu với việc updatevalue
, onChange
, và onBlur
. Thay đổi update thuộc tính từ render props
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
/>
Bạn có thể touch thuộc tính trước khi báo lỗi
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email && "error"}
/>
Nếu có lỗi, nó sẽ hiển thị cho user thấy
Field input sẽ trông như sau
<label htmlFor="email">Email</label>
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email && "error"}
/>
{errors.email && touched.email && (
<div className="input-feedback">{errors.email}</div>
)}
Render Props trong field Password
Bây giờ tiếp đến là password. Các bước tương tự như email
<label htmlFor="password">Password</label>
<input
id="password"
name="password"
type="password"
placeholder="Enter your password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
className={errors.password && touched.password && "error"}
/>
{errors.password && touched.password && (
<div className="input-feedback">{errors.password}</div>
)}
Testing Validation
Đầu tiên với trường hợp không nhập gì cả. Message error sẽ được hiển thị như sau

Trường hợp khác. Chúng ta click vào input email nhưng không nhập gì cả

Sau đó click ra ngoài input chúng ta sẽ thấy message Required. Mà không cần load lại trang như click button trong trường hợp trên

Chúng ta nhập không đúng với định dạng email

Nhập đúng định dạng email và không thấy lỗi nào hiển thị

Làm điều tương tự với password. Click vào không nhập gì cả và click bên ngoài input

Bạn sẽ nhập password nhưng không đủ độ dài

Bây giờ bạn nhập đủ kí tự nhưng không nhập số

Cuối cùng chúng ta thêm số vào. Và message error không xuất hiện

Kết luận
Qua bài viết bạn có thể tạo form check validation app React, với Formik và Yum.
Tham khảo thêm React : Bí quyết lập trình React cho người mới bắt đầu

Bài viết này được sưu tầm và tổng hợp từ nhiều nguồn trên Internet.
Nếu có gì không hiểu thì inbox messenger bên dưới mình hỗ trợ thêm nhé.