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
相关产品推荐
相关产品推荐

