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

react-hook-form中如何让Yup支持null默认值但提交时禁止null

解决方案

Yup原生提供了对应API实现这个需求,不需要手写Nullable这类hack类型,核心是调整schema定义的链式顺序,匹配表单「初始空态允许null/空值、提交时必须符合类型规则」的场景。

修正后的Yup Schema写法

使用Yup内置的nullable()方法声明字段允许接收null作为输入态,注意链式调用顺序:nullable()必须放在required()之前,让校验逻辑先放行null值,再由required()优先拦截空态返回必填提示,避免空值直接触发类型错误。

import { object, number, date, InferType } from 'yup';
import { startOfToday } from 'date-fns';

export const ExpectedIncomeSchema = object({
  newIncome: number()
    .transform((value) => value === '' ? null : value) // 可选:如果输入框默认是空字符串,统一转null处理
    .nullable() // 原生声明字段允许接收null,匹配表单初始空态
    .required('请输入预期收入') // 优先拦截null/undefined空值,返回必填提示
    .typeError('请输入有效的数字') // 仅当输入非空、但类型不符合时才触发类型错误
    .min(0, '收入不能小于0')
    .integer('收入必须为整数'),
  fromDate: date()
    .nullable()
    .required('请选择生效日期')
    .typeError('请选择有效的日期')
    .min(startOfToday(), '生效日期不能早于今日'),
});

// 自动推导校验通过后的最终提交值类型,自动排除null,不需要额外手动定义
export type ExpectedIncomeValues = InferType<typeof ExpectedIncomeSchema>;

配合react-hook-form使用

schema调整完成后,yupResolver会自动识别表单输入态允许null值,设置defaultValues为null时既不会触发TypeScript类型错误,空态提交时也会正确返回必填提示,而非类型错误:

import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';

const methods = useForm({
  resolver: yupResolver(ExpectedIncomeSchema),
  defaultValues: {
    newIncome: null,
    fromDate: null,
  },
});

关键规则说明

  • Yup校验按链式调用顺序执行,必须先调用nullable()放行null值,再调用required()做非空校验,否则空值会先触发类型错误
  • nullable()仅放开输入阶段的null类型限制,不会绕过required()的非空校验,校验通过后的提交值类型会自动排除null
  • 如果使用的输入组件默认返回空字符串""而非null,加一层transform做值转换即可,不需要调整后续校验规则

之前的hack方案问题原因

手动写Nullable泛型只是在TypeScript层面强行给字段加上了null类型,但是Yup schema本身没有声明字段可空,校验时会直接把null判定为类型不匹配,优先触发typeError,根本不会走到required的校验逻辑,自然无法返回预期的必填提示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:27:28