Next.js与zod组件搭档,轻松优雅做表单数据验证

1,057 阅读3分钟

在 Next.js 中使用 Zod 可以帮助你进行表单验证和类型安全检查。

Zod 是一个 TypeScript-first 的验证库,能很好地与 TypeScript 和 Next.js 配合使用,提升开发体验。

下面是一个具体而实用的教程,介绍如何在 Next.js 项目中与 Zod 一起使用。

1. 安装依赖

首先,需要安装 Zod 和相关的依赖:

npm install zod

如果你还没有安装 nextreact,可以运行以下命令来安装:

npm install next react react-dom

2. 设置 Zod 验证模式

Zod 提供了非常简单的 API 来定义验证规则。假设你要创建一个用户注册表单,验证用户的邮箱、用户名和密码。

在你的项目中创建一个 validators.ts 文件,用于集中管理 Zod 验证规则:

// validators.ts
import { z } from 'zod';

// 定义一个用户注册表单的验证模式
export const registerSchema = z.object({
  username: z.string().min(3, { message: "用户名必须至少为 3 个字符" }),
  email: z.string().email({ message: "无效的电子邮箱" }),
  password: z.string().min(6, { message: "密码必须至少为 6 个字符" }),
});

3. 创建表单组件

在 Next.js 项目中,你可以使用 React 来创建表单组件,并通过 Zod 来验证表单数据。以下是一个使用 react-hook-form 和 Zod 结合的示例,react-hook-form 用于处理表单状态,Zod 用于进行数据验证。

首先,安装 react-hook-form@hookform/resolvers

npm install react-hook-form @hookform/resolvers

然后,创建一个表单组件 RegisterForm.tsx

// components/RegisterForm.tsx
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { registerSchema } from '../validators';

type FormData = {
  username: string;
  email: string;
  password: string;
};

const RegisterForm = () => {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(registerSchema),  // 使用 Zod 进行表单验证
  });

  const onSubmit = (data: FormData) => {
    console.log('提交的数据:', data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="form">
      <div>
        <label htmlFor="username">用户名</label>
        <input
          id="username"
          type="text"
          {...register('username')}
        />
        {errors.username && <p>{errors.username.message}</p>}
      </div>

      <div>
        <label htmlFor="email">邮箱</label>
        <input
          id="email"
          type="email"
          {...register('email')}
        />
        {errors.email && <p>{errors.email.message}</p>}
      </div>

      <div>
        <label htmlFor="password">密码</label>
        <input
          id="password"
          type="password"
          {...register('password')}
        />
        {errors.password && <p>{errors.password.message}</p>}
      </div>

      <button type="submit">提交</button>
    </form>
  );
};

export default RegisterForm;

4. 在页面中使用表单组件

pages 目录下创建一个页面文件 register.tsx 来展示和使用注册表单:

// pages/register.tsx
import React from 'react';
import RegisterForm from '../components/RegisterForm';

const RegisterPage = () => {
  return (
    <div>
      <h1>注册</h1>
      <RegisterForm />
    </div>
  );
};

export default RegisterPage;

5. 运行项目

完成以上步骤后,运行你的 Next.js 项目:

npm run dev

访问 http://localhost:3000/register,你就可以看到一个带有表单验证的注册表单。当你输入不符合要求的数据时,Zod 会返回相应的错误信息。

6. Zod 与 Next.js API 路由结合使用

如果你需要在 Next.js API 路由中也使用 Zod 来验证请求体数据,可以通过如下方式进行验证:

// pages/api/register.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { registerSchema } from '../../validators';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    try {
      // 使用 Zod 进行请求数据验证
      const validatedData = registerSchema.parse(req.body);
      
      // 执行注册逻辑
      res.status(200).json({ message: '注册成功', data: validatedData });
    } catch (error) {
      if (error instanceof z.ZodError) {
        // 捕获 Zod 验证错误并返回错误信息
        res.status(400).json({ errors: error.errors });
      } else {
        res.status(500).json({ error: '服务器错误' });
      }
    }
  } else {
    res.status(405).json({ error: 'Method Not Allowed' });
  }
}

总结

在 Next.js 项目中使用 Zod 进行数据验证是一个很有效的方式,可以确保表单数据的安全性和准确性。

通过与 react-hook-form 配合使用,可以更轻松地管理表单状态,同时通过 zodResolver 轻松将 Zod 集成到表单验证中。

使用 Zod 还可以确保 TypeScript 类型与数据验证的一致性,提升开发体验。