React Hook表单中的自定义验证规则

1,073 阅读3分钟

上一篇文章中,我们使用React Hook Form来构建一个表单,以捕获姓名、电子邮件地址和分数。我们在所有的字段上实现了必要的验证规则:

在这篇文章中,我们将在同一个表单上实现更复杂的验证规则。

一个字段上的多个验证规则

我们将首先为分数字段添加额外的规则。它已经有一个必填的验证规则,但现在我们要确保分数在0到100之间:

<input
  type="number"
  id="score"
  name="score"
  ref={register({
    required: true,
    min: 0,    max: 100  })}
/>

我们可以用React Hook Form的minmax 标准规则来实现这一点。

当这些规则被破坏时,我们还可以渲染有用的验证错误信息:

{
  errors.score && errors.score.type === "min" && (
    <div className="error">Your score must be at least 0</div>
  );
}
{
  errors.score && errors.score.type === "max" && (
    <div className="error">Your score must be no more than 100</div>
  );
}

我们使用type 属性来确定验证错误是针对哪条规则的,然后呈现一个适当的消息。

自定义验证规则

让我们在分数字段上实现另一个规则。现在我们要确保分数是一个偶数。这个规则不存在于React Hook Form中,所以我们需要实现一个自定义验证规则。下面是这个规则的函数:

const isEven = (score: number) => score % 2 === 0;

下面是我们如何将这个规则与分数字段连接起来:

<input
  type="number"
  id="score"
  name="score"
  ref={register({
    required: true,
    min: 0,
    max: 100,
    validate: isEven  })}
/>

因此,我们将register functions对象参数中的validate 属性设置为验证器函数。React Hook Form的自定义验证器函数接收字段的值,如果规则通过则返回true ,如果规则失败则返回false

让我们在这个规则失败时渲染一个错误信息:

{
  errors.score && errors.score.type === "validate" && (
    <div className="error">Your score must be and even number</div>
  );
}

自定义验证规则错误的type 属性是"validate"

异步验证

一些自定义验证规则需要调用网络服务到后端来进行检查。这些规则的验证器函数是异步的。让我们看看我们如何在React Hook Form中实现一个异步验证规则。

我们将在电子邮件地址上实现一个规则,以检查它是否是唯一的。我们将用下面的emailIsUnique 函数来伪造后端检查:

const emailIsUnique = async (email: string) => {
  await wait(1000);
  return email !== "someone@somewhere.com";
};

const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

我们将自定义异步验证器函数与同步验证器函数连接起来:

<input
  type="email"
  id="email"
  name="email"
  ref={register({
    required: true,
    validate: emailIsUnique  })}
/>

如果这个规则失败了,让我们呈现一个错误信息:

{
  errors.email && errors.email.type === "validate" && (
    <div className="error">This email address already exists</div>
  );
}

CodeSandbox中可以找到这个表单的一个工作例子。

总结

用React Hook Form实现自定义验证规则是超级简单的。也支持异步的自定义验证规则。

下一篇文章中,我们将深入探讨如何用React Hook Form实现主细节表单。