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

React useForm结合Zod配置可选输入遇「Expected string, received nan」错误求助

React useForm + Zod 可选数字输入报错:Expected string, received nan

问题重现

在React useForm中搭配Zod实现可选折扣输入时,明明设置了非必填规则,却始终收到错误提示:Expected string, received nan。

Zod Schema 代码

discount: z
    .string()
    .optional()
    .transform((discount) =>
      discount === "" || discount === undefined ? undefined : parseInt(discount)
    )
    .pipe(z.number().nonnegative().max(100)),

FormInput 组件代码

<FormInput<FormData, InputProps>
          id="DiscountFormCreateProduct"
          register={register}
          rules={{ required: false, valueAsNumber: true }}
          errors={errors}
          className="col-span-3"
          name="discount"
          labelText="Discount"
          label="Discount number "
          Formtype={FormElementType.INPUT}
          placeholder="Discount(Eg 5%)"
          isRequired={false}
          type="number"
          min={0}
          max={100}
        />

问题原因

  1. 类型不匹配:Zod Schema定义的是z.string()类型,但useForm的valueAsNumber: true会将输入值强制转为数字。当输入为空时,这个转换会得到NaN,而Zod期望接收string类型,直接触发类型校验错误。
  2. Transform逻辑失效:空输入时,valueAsNumber已经把值转成了NaN,导致Zod的transform函数接收到的不是预期的""或undefined,无法按逻辑转为undefined,后续的pipe校验自然失败。

解决方案

方案一:调整Zod Schema适配数字输入(推荐)

因为输入是type="number",直接让Zod处理数字类型,同时兼容空输入产生的NaN:

discount: z
  .unknown()
  .transform((val) => {
    if (val === "" || val === undefined || Number.isNaN(val)) {
      return undefined;
    }
    return typeof val === "number" ? val : parseInt(val);
  })
  .pipe(z.number().nonnegative().max(100).optional()),

或者用Zod的优秀END chart(AD真诚YN费 Events( Default

I的:不对,用更简洁的coerce方法自动处理类型转换:

discount: z.coerce
  .number()
  .nonnegative()
  .max(100)
  .optional()
  .transform((val) => Number.isNaN(val) ? undefined : val),

方案二:移除useForm的valueAsNumber,保持字符串输入

去掉register配置里的valueAsNumber: true,让输入值保持string类型,适配原来的Zod Schema逻辑:

<FormInput<FormData, InputProps>
  // ...其他属性保持不变
  rules={{ required: false }} // 移除valueAsNumber配置
/>

此时空输入会传递""给Zod,transform函数能正确转为undefined,顺利通过后续的数字校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:50:23