
1. Khởi tạo dự án Next.js
Trước tiên, hãy tạo một dự án Next.js mới. Bạn có thể sử dụng công cụ create-next-app
để khởi tạo dự án:
npx create-next-app@latest my-nextjs-app
Trong quá trình khởi tạo, bạn sẽ được hỏi về việc sử dụng TypeScript, ESLint và các cấu hình khác. Hãy lựa chọn theo nhu cầu của bạn.
2. Cài đặt các thư viện cần thiết
Sau khi khởi tạo dự án, di chuyển vào thư mục dự án và cài đặt các thư viện sau:
cd my-nextjs-app
npm install react-hook-form zod @hookform/resolvers
npx shadcn-ui@latest init
react-hook-form
: Thư viện giúp quản lý trạng thái và xử lý biểu mẫu trong React.zod
: Thư viện xác thực và định hình dữ liệu cho JavaScript và TypeScript.@hookform/resolvers
: Cung cấp các trình giải quyết để tích hợp các thư viện xác thực (như Zod) với React Hook Form.shadcn-ui
: Tập hợp các thành phần giao diện người dùng có thể tái sử dụng, giúp bạn dễ dàng xây dựng giao diện nhất quán và hiện đại.
3. Thiết lập cấu trúc dự án
Tạo các thư mục và tệp tin cần thiết cho dự án:
my-nextjs-app/
├── components/
│ └── RegisterForm.tsx
└── pages/
└── register.tsx
components/RegisterForm.tsx
: Chứa thành phần biểu mẫu đăng ký.pages/register.tsx
: Trang đăng ký sử dụng thành phầnRegisterForm
.
4. Xây dựng thành phần RegisterForm
Trong tệp components/RegisterForm.tsx
, bạn sẽ xây dựng biểu mẫu đăng ký với các trường như tên người dùng, email và mật khẩu. Sử dụng các thành phần từ shadcn-ui
để tạo giao diện và tích hợp React Hook Form cùng Zod để quản lý và xác thực dữ liệu.
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from 'shadcn-ui/form';
import { Input } from 'shadcn-ui/input';
import { Button } from 'shadcn-ui/button';
// Định nghĩa schema xác thực với Zod
const schema = z.object({
username: z.string().min(1, 'Tên người dùng là bắt buộc'),
email: z.string().email('Email không hợp lệ'),
password: z.string().min(6, 'Mật khẩu phải có ít nhất 6 ký tự'),
});
// Định nghĩa kiểu dữ liệu dựa trên schema
type FormData = z.infer<typeof schema>;
const RegisterForm: React.FC = () => {
// Sử dụng useForm với zodResolver để tích hợp schema xác thực
const form = useForm<FormData>({
resolver: zodResolver(schema),
});
// Hàm xử lý khi biểu mẫu được gửi
const onSubmit = (data: FormData) => {
console.log('Dữ liệu gửi đi:', data);
// Thực hiện các hành động khác như gọi API để đăng ký người dùng
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField name="username" control={form.control}>
{({ field }) => (
<FormItem>
<FormLabel>Tên người dùng</FormLabel>
<FormControl>
<Input placeholder="Nhập tên người dùng" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
</FormField>
<FormField name="email" control={form.control}>
{({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="Nhập email" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
</FormField>
<FormField name="password" control={form.control}>
{({ field }) => (
<FormItem>
<FormLabel>Mật khẩu</FormLabel>
<FormControl>
<Input type="password" placeholder="Nhập mật khẩu" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
</FormField>
<Button type="submit">Đăng ký</Button>
</form>
</Form>
);
};
export default RegisterForm;
5. Tạo trang đăng ký
Trong tệp pages/register.tsx
, bạn sẽ sử dụng thành phần RegisterForm
để hiển thị biểu mẫu đăng ký.
import React from 'react';
import RegisterForm from '../components/RegisterForm';
const RegisterPage: React.FC = () => {
return (
<div className="container mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Đăng ký</h1>
<RegisterForm />
</div>
);
};
export default RegisterPage;
6. Kết luận
Bằng cách kết hợp shadcn-ui, React Hook Form và Zod trong dự án Next.js, bạn có thể xây dựng các biểu mẫu với giao diện đẹp mắt, quản lý trạng thái hiệu quả và xác thực dữ liệu mạnh mẽ. Điều này không chỉ cải thiện trải nghiệm người dùng mà còn đảm bảo tính toàn vẹn của dữ liệu trong ứng dụng của bạn.
Tham khảo thêm: