You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Zod与react-hook-form中为数字类型设置非零默认值?

如何将价格输入的默认值设为空值而非0(Zod + react-hook-form)

要实现价格输入初始为空且避免非受控错误,需要同时调整Zod校验规则、react-hook-form的默认值以及表单输入组件的处理逻辑,具体步骤如下:

1. 修改Zod Schema,支持空输入并保留正数校验

原Schema要求price必须是正数,但空输入(空字符串或null)需要被允许作为初始状态,同时提交时必须验证为有效正数。可以通过transform处理空值转换,再用refine做最终校验:

import * as z from "zod";

export const ProductSchema = z.object({
  title: z.string().min(2),
  price: z.union([z.string().optional(), z.number()])
    // 将空字符串或null转为null,其他值转为数字
    .transform(val => val === "" || val == null ? null : Number(val))
    // 提交时验证必须是非空正数
    .refine(val => val !== null && val > 0, "Price must be a positive number"),
  discount: z.number().int().min(0).max(100),
  // ...其他字段
})

export type ProductType = z.infer<typeof ProductSchema>;

也可以用更简洁的coerce方式,自动将输入转为数字(空字符串会被转为NaN,后续通过refine排除):

price: z.coerce.number()
  .nullable()
  .refine(val => val !== null && val > 0, "Price must be a positive number"),

2. 更新react-hook-form的defaultValues

将price的默认值设为null,确保初始状态有明确的受控值,避免非受控输入错误:

const form = useForm<ProductType>({
  resolver: zodResolver(ProductSchema),
  defaultValues: {
    title: "",
    price: null, // 替换原有的0
    discount: 0,
    // ...其他字段
  },
});

3. 调整Input组件的value显示

由于number类型的输入框会把null显示为文本"null",需要将null转为空字符串,保证输入框初始为空:

<FormField
  control={control}
  render={({ field }) => (
    <FormItem>
      <FormLabel>Price</FormLabel>
      <Input
        {...field}
        value={field.value ?? ""} // 关键:将null转换为空字符串
        disabled={isPending}
        placeholder="Price of product"
        type="number"
        className="shadow-sm focus:ring-primary-500 focus:border-primary-500 sm:text-sm border-gray-300 rounded-md bg-white"
      />
      <FormMessage>{errors.price?.message}</FormMessage>
    </FormItem>
  )}
  name="price"
/>

这样设置后,输入框初始为空,符合需求;同时react-hook-form保持受控状态,Zod会在提交时校验价格必须为正数,空输入会触发对应的错误提示。

内容的提问来源于stack exchange,提问作者Apollo Vostok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:10:14