React-hook-form输入字段匹配验证最佳实践

时间:2020-03-26 18:11:11

标签: reactjs react-hook-form

在处理React-hook-form时,输入字段匹配验证的最佳实践是什么?例如,当匹配email输入时,等等。

在研究使用React-hook-form进行电子邮件匹配验证时,尝试通过其验证方法将错误消息与“耦合元素”分开时,发现了一个问题。 ref仅采用一个用于React-hook形式register的参数,而需要使用useRef访问current.value进行值匹配,如下所示:< / p>

import React, { useRef } from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

function App() {
  const { register, handleSubmit, errors } = useForm();
  const inputEmail = useRef(null)
  const onSubmit = data => {
    console.log('onSubmit: ', JSON.stringify(data))
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="email">Email</label>
      <input
        name="email"
        type="email"
        ref={inputEmail}
      />
      {/* desired: show `email` error message */}
      <label htmlFor="email">Email confirmation</label>
      <input
        name="emailConfirmation"
        type="email"
        ref={register({
          validate: {
            emailEqual: value => (value === inputEmail.current.value) || 'Email confirmation error!',
          }
        })}
      />
      {errors.emailConfirmation && <p>{errors.emailConfirmation.message}</p>}
      <input type="submit" />
    </form>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

虽然在进行输入字段匹配时此模式似乎是一个选项,但它在React-hook-form中不能很好地发挥作用!

例如,错误消息仅与一个输入用例耦合,并且对于每个独立字段没有单独的消息,或者输入字段之一没有分配寄存器,这意味着属性{{1} }尚未设置,等等。

因此,我正在研究一种解决以下问题的良好做法或模式:

  • 保留由输入字段分隔的错误消息
  • 验证方法在测试匹配项时应该能够以React兼容的方式引用双字段值,而不是 通过DOM(document.querySelector等)

2 个答案:

答案 0 :(得分:5)

您不需要inputEmail的手动参考。而是使用getValues方法来获取整个表单的当前值。

const { register, getValues } = useForm()

然后您同时注册两个输入并通过自定义验证调用getValues

  <input
    name="email"
    type="email"
    ref={register}
  />
  <input
    name="emailConfirmation"
    type="email"
    ref={register({
      validate: {
        emailEqual: value => (value === getValues().email) || 'Email confirmation error!',
      }
    })}
  />

答案 1 :(得分:1)

为此,您可以使用Yup库,这很不错:

在实例化validationSchema并传递有效的useForm模式时,将Yup添加到配置对象中。像这样:

const Schema = yup.object().shape({
  email: yup.string().required('Required field'),
  emailConfirmation: yup
    .string()
    .oneOf([yup.ref('email')], 'Emails must match')
    .required('Required field'),
});

// How to add it to your useForm
const { register } = useForm({
  validationSchema: Schema
})

您的组件应如下所示:

function App() {
  const { register, handleSubmit, errors } = useForm({
    validationSchema: Schema
  });

  const onSubmit = data => {
    console.log('onSubmit: ', JSON.stringify(data))
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="email">Email</label>
      <input
        name="email"
        type="email"
        ref={register}
      />
      {/* desired: show `email` error message */}
      <label htmlFor="email">Email confirmation</label>
      <input
        name="emailConfirmation"
        type="email"
        ref={register}
      />
      {errors.emailConfirmation && <p>{errors.emailConfirmation.message}</p>}
      <input type="submit" />
    </form>
  );
}
相关问题