next中shadcn、React Hook Form、zod 使用教程

要在 Next 项目中结合 shadcn、React Hook Form 和 zod 使用表单验证,可以按照以下步骤来设置和使用这些工具。我们将搭建一个简单的表单,包含姓名和邮箱字段,并使用 zod 进行表单验证, React Hook Form 管理表单状态

1. 安装依赖

首先,确保安装所需的库。

javascript 复制代码
npm install @hookform/resolvers react-hook-form zod

2. 定义表单验证 Schema

使用 zod 定义表单字段的验证规则。zod 的 Schema 将帮助我们在表单中验证输入数据。

javascript 复制代码
// src/schemas/userFormSchema.js

import { z } from 'zod';

export const userFormSchema = z.object({
  name: z.string().min(1, { message: '姓名不能为空' }),
  email: z.string().email({ message: '无效的邮箱格式' }),
});

3. 创建表单组件

在表单组件中使用 React Hook Form 和 zodResolver。

zodResolver 是一个适配器,它将 Zod 的 schema 用于 React Hook Form 的验证。在提交表单时,它会自动验证输入数据是否符合 Zod 定义的规则。

javascript 复制代码
// src/components/UserForm.js

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { userFormSchema } from '@/schemas/userFormSchema';
import { useState } from 'react';

export default function UserForm() {
  const [submitMessage, setSubmitMessage] = useState('');
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(userFormSchema),
  });

  const onSubmit = (data) => {
    console.log('Form Data:', data);
    setSubmitMessage('表单提交成功');
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      {/* 姓名字段 */}
      <div>
        <label className="block text-sm font-medium text-gray-700">姓名</label>
        <input
          type="text"
          {...register('name')}
          className="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
        />
        {errors.name && <p className="text-sm text-red-500">{errors.name.message}</p>}
      </div>

      {/* 邮箱字段 */}
      <div>
        <label className="block text-sm font-medium text-gray-700">邮箱</label>
        <input
          type="email"
          {...register('email')}
          className="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
        />
        {errors.email && <p className="text-sm text-red-500">{errors.email.message}</p>}
      </div>

      {/* 提交按钮 */}
      <button
        type="submit"
        className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
      >
        提交
      </button>

      {/* 提交状态信息 */}
      {submitMessage && <p className="text-sm text-green-500">{submitMessage}</p>}
    </form>
  );
}

4. 使用 shadcn UI 组件样式

通过 shadcn 的样式,可以自定义表单的外观。例如,可以将输入框样式更改为 @/components/ui/input 或按钮样式为 @/components/ui/button。

javascript 复制代码
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';

export default function UserForm() {
  // 代码同上
  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <div>
        <label className="block text-sm font-medium text-gray-700">姓名</label>
        <Input type="text" {...register('name')} />
        {errors.name && <p className="text-sm text-red-500">{errors.name.message}</p>}
      </div>
      <div>
        <label className="block text-sm font-medium text-gray-700">邮箱</label>
        <Input type="email" {...register('email')} />
        {errors.email && <p className="text-sm text-red-500">{errors.email.message}</p>}
      </div>
      <Button type="submit">提交</Button>
      {submitMessage && <p className="text-sm text-green-500">{submitMessage}</p>}
    </form>
  );
}

5. 将组件添加到页面

在页面文件中导入并使用 UserForm 组件:

javascript 复制代码
import UserForm from '@/components/UserForm';

export default function HomePage() {
  return (
    <div className="p-4">
      <h1 className="text-xl font-semibold">用户注册</h1>
      <UserForm />
    </div>
  );
}
相关推荐
deli00710 分钟前
为什么最近邻路线总在绕远?2-opt 把 50 城 TSP 缩短了 20.9%
前端
guslegend14 分钟前
底层数据设计:读写分离、分库分表与热点数据隔离
前端
Southern Wind16 分钟前
AIAgent——第一章:本地 Agent 与 Vue 3 流式全栈实战
前端·javascript·vue.js
可乐鸡翅yeah_24 分钟前
HLS 业务 Referer‑Policy 网页元标签引发播放异常排错
前端·javascript·网络·ffmpeg·php·音视频
jj_ccwgw24 分钟前
从 0 到 1 搭建 pnpm + Workspaces + Turborepo Monorepo 保姆级指南
前端·node.js
智驭未来掌门人25 分钟前
AI编程时代的设计系统落地指南:从分类选型到项目实战
前端
vipxieliang28 分钟前
深入理解 JavaScript 数据类型与类型转换
前端·javascript
用户157415681653433 分钟前
告别硬编码下拉选项:Vue 3 企业项目字典化改造实录
前端
明航咨询-陈老师36 分钟前
2026信创“硬门槛“解码:国测(Ⅲ级首现/首个Ⅱ级OS) × LS(LS1-4) 双资质实操对照
前端
前端snow41 分钟前
别再死磕单 Agent 了!多智能体架构 + LangGraph 实战,一篇全讲透
前端