Giới thiệu
React Hook Form là một thư viện quản lý form dành cho React, được phát triển bởi nhóm của Bluebill. Thư viện này tập trung vào hiệu suất và API tối giản, giúp cho các dự án nhẹ hoặc ưu tiên hiệu suất có thể sử dụng nó một cách dễ dàng.
So với Formik, React Hook Form có kích thước nhỏ hơn gấp đôi và không có dependency. Điều này giúp cho việc sử dụng React Hook Form trở nên đơn giản và ít tốn tài nguyên hơn.
Ngoài ra, React Hook Form cũng có khả năng xử lý hiệu quả các component của form, giúp tránh tình trạng re-render không cần thiết và tăng hiệu suất ứng dụng .
Tuy nhiên, Formik lại cung cấp một hệ thống validation phong phú hơn, hỗ trợ xử lý lỗi và có một hệ sinh thái lớn hơn.
Vì vậy, nếu bạn đang tìm kiếm một thư viện quản lý form đơn giản và hiệu suất cao, React Hook Form là một lựa chọn tốt. Nếu bạn muốn có một hệ thống validation phong phú và hỗ trợ xử lý lỗi tốt hơn, Formik là sự lựa chọn đáng cân nhắc
Cài đặt
Install package
npm install react-hook-form
// or
yarn add react-hook-form
Tạo component mới, thêm đoạn code như sau:
import { useForm } from 'react-hook-form';
const ReactHookFormExample = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data: any) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('firstName')} placeholder="First Name" />
<input {...register('lastName')} placeholder="Last Name" />
<button type="submit">Submit</button>
</form>
);
}
export default ReactHookFormExample;
Register fields: Sử dụng register để đăng ký các trường input trong form. Mỗi trường cần có một name. Trong ví dụ trên, chúng ta đã đăng ký hai trường là firstName và lastName.
One of the key concepts in React Hook Form is to register your component into the hook. This will make its value available for both the form validation and submission.
Note: Each field is required to have a name as a key for the registration process.
Xử lý sự kiện submit: Sử dụng handleSubmit để xử lý sự kiện submit của form. Khi form được submit, hàm onSubmit sẽ được gọi với dữ liệu của form.
Kiểm tra error và hiển thị thông báo error: Thông tin về lỗi của các field sẽ được lưu trong errors. Bạn có thể kiểm tra errors để hiển thị thông báo lỗi tương ứng cho từng field.import { useForm } from 'react-hook-form';
const ReactHookFormExample = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data: any) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input placeholder='first name'
{...register("firstName", { required: true })}
aria-invalid={errors.firstName ? "true" : "false"}
/>
{errors.firstName?.type === "required" && (
<p role="alert">First name is required</p>
)}
<input placeholder='email'
{...register("mail", { required: "Email Address is required" })}
aria-invalid={errors.mail ? "true" : "false"}
/>
{errors.mail && <p role="alert">{errors.mail?.message?.toString()}</p>}
<input type="submit" />
</form>
);
}
export default ReactHookFormExample;
setError
setError dùng để set lỗi cho một element.
Hook useForm sẽ cung cấp cho chúng ta một đối tượng có thuộc tính errors. Thuộc tính này chứa tất cả các lỗi đã được tìm thấy trong form.
Cú phápsetError: (name: string, error: FieldError, { shouldFocus?: boolean }) => void
Name | Type | Description |
---|---|---|
name | string | input's name. |
error | { type: string, message?: string, types: MultipleFieldErrors } | Set an error with its type and message. |
config | { shouldFocus?: boolean } | Should focus the input during setting an error. This only works when the input's reference is registered, it will not work for custom register as well. |
Xem thêm: React-hook-form: setError
Ví dụ:import { useForm } from 'react-hook-form';
const ReactHookFormExample = () => {
const { register, handleSubmit, setError, formState: { errors } } = useForm();
const onSubmit = (data: any) => {
debugger;
if (data.firstName.length < 6) {
setError('firstName', {
type: 'manual',
message: 'Vui lòng nhập tên người dùng',
});
return;
}
// Tiếp tục xử lý dữ liệu hoặc gửi yêu cầu API
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input placeholder='first name'
{...register("firstName", { required: true })}
aria-invalid={errors.firstName ? "true" : "false"}
/>
{errors.firstName && <p style={{ color: 'red' }}>{errors.firstName.message?.toString()}</p>}
<input placeholder='email'
{...register("mail", { required: "Email Address is required" })}
aria-invalid={errors.mail ? "true" : "false"}
/>
{errors.mail && <p role="alert">{errors.mail?.message?.toString()}</p>}
<input type="submit" />
</form>
);
}
export default ReactHookFormExample;
Chúng ta sử dụng type trong setError để xác định loại lỗi, ví dụ: 'manual', 'required'.
Ví dụ:{errors.password && errors.password.type === 'required' && (
<p style={{ color: 'red' }}>{errors.password.message}</p>
)}
{errors.mail && <p role="alert">{errors.mail?.message?.toString()}</p>}
Controller
Controller là một thành phần quan trọng trong thư viện React Hook Form. Nó được sử dụng để quản lý và kiểm soát các trường input trong biểu mẫu (form) của bạn và tương tác với React Hook Form
Khai báo các hook và Controller
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
Khởi tạo React Hook và thêm Controller
const ReactHookFormExample = () => {
const { register, handleSubmit, setError, formState: { errors }, control } = useForm();
const onSubmit = (data: any) => {
debugger;
console.log(data);
if (data.email.length < 6) {
setError('email', {
type: 'manual',
message: 'Vui lòng nhập tên người dùng',
});
return;
}
console.log(data);
};
return (
<>
<h2>React Hook Form</h2>
<form onSubmit={handleSubmit(onSubmit)}>
<input placeholder='first name'
{...register("firstName", { required: true })}
aria-invalid={errors.firstName ? "true" : "false"}
/>
<Controller
name="email"
control={control}
defaultValue=""
rules={{
required: 'Email is required',
pattern: {
value: /\S+@\S+\.\S+/,
message: 'Invalid email address',
},
}}
render={({ field }) => <input {...field} placeholder="your email" />}
/>
{errors.email && <p>{errors.email.message?.toString()}</p>}
<button type="submit">Submit</button>
<p>Test</p>
</form>
</>
);
}
export default ReactHookFormExample;
- name: Đây là tên của field input
- control: Prop này truyền từ useForm và là bắt buộc. Nó kết nối Controller với React Hook Form.
- defaultValue: Điều này đặt giá trị mặc định của field input
- render: Prop này nhận một hàm với đối số field để render field input. Bạn cần sử dụng ...field để truyền các props cần thiết cho trường input như value, onChange, và onBlur.
- Thêm các validation vào bằng cách sử dụng rule trong Controller
hookform/resolvers
@hookform/resolvers là một module tùy chọn cho phép bạn validate các giá trị của React Hook Form với library validation. Hiện tại, hookform/resolvers hỗ trợ 5 libraries: Yup, Zod, Vest, Joi và Superstruct
Trong ví dụ này, mình sử dụng yup. Tham khảo thêm về Yup tại đây React: Yup - Day 10
Cài đặt
yarn add @hookform/resolvers
yarn add yup
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers';
import * as yup from 'yup';
const schema = yup.object().shape({
name: yup.string().required('Name is required'),
email: yup.string().email('Email is not valid').required('Email is required'),
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (data) => {
console.log(data);
};
return (
<div>
<h1>Register form/h1>
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<input type="text" {...register('name')} />
<p>{errors.name?.message}</p>
</div>
<div>
<input type="text" {...register('email')} />
<p>{errors.email?.message}</p>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
Trường hợp bạn muốn debug
resolver: async (data, context, options) => {
// you can debug your validation schema here
console.log("formData", data)
console.log(
"validation result",
await anyResolver(schema)(data, context, options)
)
return anyResolver(schema)(data, context, options)
}
Ngoài Yup, bạn có thể sử dụng các thư viện khác như Zod, Joi, Vest, Ajv.
Tham khảo
React Hook Form vs. Formik: Simplifying Form Management in React
Nhận xét
Đăng nhận xét