一个跨字段的验证规则是指规则依赖于多个字段。这篇文章介绍了如何在React Hook Form中实现这些类型的验证规则。

一个例子
我们有下面这个表单,可以捕捉到低分和高分:
type Scores = {
low: number;
high: number;
};
const ScoreForm = () => {
const { register, handleSubmit } = useForm<Scores>();
const onSubmit = (data: Scores) => {
console.log("data", data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="field">
<label htmlFor="low">Lowest score</label>
<input type="number" id="low" name="low" ref={register} />
</div>
<div className="field">
<label htmlFor="high">Highest score</label>
<input type="number" id="high" name="high" ref={register} />
</div>
<button type="submit">Save</button>
</form>
);
};
这是一个直接的React Hook Form,目前还没有验证规则。
添加简单的验证
分数是强制性的,我们希望它们是在0到10之间。实现这些规则是非常简单的:
const ScoreForm = () => {
const {
register,
handleSubmit,
errors } = useForm<Scores>();
...
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="field">
<label htmlFor="low">Lowest score</label>
<input
type="number"
id="low"
name="low"
ref={register({
required: true, min: 0, max: 10 })}
/>
{errors.low && errors.low.type === "required" && ( <div className="error">You must enter a score.</div> )} {errors.low && errors.low.type === "min" && ( <div className="error">The score must be at least 0.</div> )} {errors.low && errors.low.type === "max" && ( <div className="error">The score can't be more than 10.</div> )} </div>
<div className="field">
<label htmlFor="high">Highest score</label>
<input
type="number"
id="high"
name="high"
ref={register({
required: true, min: 0, max: 10 })}
/>
{errors.high && errors.high.type === "required" && ( <div className="error">You must enter a score.</div> )} {errors.high && errors.high.type === "min" && ( <div className="error">The score must be at least 0.</div> )} {errors.high && errors.high.type === "max" && ( <div className="error">The score can't be more than 10.</div> )} </div>
<button type="submit">Save</button>
</form>
);
};
表单字段现在捕获了0到10之间的低分和高分。
添加跨字段验证
你能发现验证规则中的一个缺口吗?
是的,没错--低分可以比高分更高!我们来实现一个额外的验证规则。
让我们实现一个额外的验证规则,以检查低分不高于高分的情况。这个规则是一个跨字段验证规则的例子,因为它是基于多个字段的--它同时依赖于低分和高分字段。
我们可以通过自定义验证规则在React Hook Form中实现跨字段验证规则。
首先,我们需要将 getValues从React Hook Form。这个函数允许我们访问表单上的任何字段值。我们将需要在我们的自定义验证器函数中使用这个:
const {
register,
handleSubmit,
errors,
getValues,} = useForm<Scores>();
现在让我们在高分字段上实现自定义验证规则:
<input
type="number"
id="high"
name="high"
ref={register({
required: true,
min: 0,
max: 10,
validate: () => Number(getValues("low")) <= Number(getValues("high")) })}
我们将register 函数的对象参数中的validate 属性设置为一个内联验证器函数。React Hook Form的自定义验证器函数如果通过则返回true ,如果规则失败则返回false 。我们使用getValues 函数来获取验证器函数中的相关字段值。这些字段的值是字符串,所以我们使用 Number构造函数将其转换为数字,然后再进行检查。
很好!
让我们添加验证错误信息:
<input
type="number"
id="high"
...
/>
...
{errors.high && errors.high.type === "validate" && ( <div className="error"> The highest score can't be less than the lowest score. </div>)}
type 自定义验证规则错误的属性是 "validate"。
当表单被提交时,验证错误会出现在无效的高分字段旁边:

我们也可以给低分字段添加这个规则,但没有必要。
总结
你可以使用自定义验证规则来实现React Hook Form中的跨域验证。必须使用getValues 函数来获取验证器函数中规则所依赖的字段值。