zod 模式不会针对空字符串触发 required_error

问题描述 投票:0回答:1

我正在使用

zod
库来验证 Next.js 应用程序中的表单。我已经为订阅表单定义了一个架构,该表单应该验证
email
字段。我想在
Email is required
字段留空时显示自定义错误消息 -
email
,但由于某种原因,
required_error
属性未按预期工作。如果我点击
Subscribe
而不输入任何电子邮件,我会收到错误消息
Email is invalid
,而不是错误消息
Email is required

这是我的架构:

export const subscribeSchema = z.object({
  email: z
    .string({ required_error: "Email is required" })
    .email({ message: "Email is invalid" }),
});

这是我在订阅表单中使用架构的方式:

"use client";

import * as React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { useRouter } from "next/navigation";

import { cn } from "@/lib/util";
import { subscribeSchema } from "@/lib/validations/auth";
import { buttonVariants } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Icons } from "@/components/icons";
import { subscribeUser } from "@/lib/subscribe-user";

export type FormData = z.infer<typeof subscribeSchema>;

export function SubscribeForm() {
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<FormData>({ resolver: zodResolver(subscribeSchema) });

  const [isLoading, setIsLoading] = React.useState<boolean>(false);
  const [error, setError] = React.useState<string | null>(null);

  const router = useRouter();

  async function onSubmit(submittedData: FormData) {
    await subscribeUser({
      submittedData,
      setError,
      router,
      setIsLoading,
      reset,
    });
  }

  return (
    <div className="grid gap-6 rounded-md border border-neutral-200 bg-neutral-100 p-6">
      <div className="flex flex-col space-y-1">
        <h1 className="text-2xl">Subscribe</h1>
        <p>Get notified of the course launch.</p>
      </div>
      {error && (
        <p className="text-sm text-red-500 animate-in fade-in-0 slide-in-from-left-1">
          {error}
        </p>
      )}
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="grid gap-6">
          <div className="grid gap-1">
            <Label htmlFor="email">Email</Label>
            <Input
              className="bg-white"
              id="email"
              type="email"
              placeholder="[email protected]"
              autoCapitalize="none"
              autoComplete="email"
              autoCorrect="off"
              disabled={isLoading}
              {...register("email")}
            />
            {errors.email && (
              <p className="px-1 text-xs text-red-600 animate-in fade-in-0 slide-in-from-left-1">
                {errors.email.message}
              </p>
            )}
          </div>
          <button className={cn(buttonVariants())} disabled={isLoading}>
            {isLoading && (
              <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
            )}
            Subscribe
          </button>
        </div>
      </form>
    </div>
  );
}

有人遇到过这个问题吗?我的架构定义中是否缺少某些内容?

任何帮助将不胜感激!

forms next.js schema next.js13 zod
1个回答
0
投票

即使没有提供输入,输入字段也会返回空字符串。 Zod 中的

required_error
属性仅在字段未注册时触发,而不是在字段为空字符串时触发。

要处理此问题,您可以使用 Zod 的

.min(1)
验证。这会检查字符串长度是否至少为 1,确保该字段不为空。以下是调整架构的方法:

export const subscribeSchema = z.object({
  email: z
    .string()
    .min(1, { message: "Email is required" }) // Makes sure the email field isn't empty
    .email({ message: "Email is invalid" }), // Checks if it's a valid email
});
© www.soinside.com 2019 - 2024. All rights reserved.