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

Posted

技术标签:

【中文标题】React-hook-form 输入字段匹配验证最佳实践【英文标题】:React-hook-form input fields match validation best practice 【发布时间】:2020-07-07 11:01:31 【问题描述】:

在处理 React-hook-form 时进行输入字段匹配验证的最佳做法是什么?比如匹配email输入等时

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

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 的配合并不好!

例如,错误消息仅与一个输入案例耦合,并且每个独立字段没有单独的消息,或者输入字段之一没有分配给它的寄存器,这意味着属性required是未设置等

所以,我正在寻找一个好的做法或模式来解决:

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

【问题讨论】:

【参考方案1】:

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

在实例化useForm 时将validationSchema 添加到您的配置对象并传递一个有效的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>
  );

【讨论】:

有没有办法在提交前验证特定字段?【参考方案2】:

您不应该需要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!',
      
    )
  />

【讨论】:

这是一个很好的答案,亚历克斯!我错过了getValues,没有意识到这一点,因为我刚刚开始使用 react-hook-forms,愉快地学习;)我相信这个问题将来对其他人有用!谢谢! 尝试在 React Native 中使用它时出现模糊错误(t.split is not a function. (In 't.split[/[,[\].]+?/)', 't.split' is undefined) [in index.cjs.js])。我认为这是因为我没有以某种方式正确初始化ref...我在.js 的顶部有import React, useEffect, useState, Fragment, ref from 'react';,在主/导出函数中有const control, handleSubmit, register, getValues, formState: errors = useForm();。有人可以在沙箱中提供一个完整的 React Native 示例吗? 忽略我的最后一条评论...我只需要像这样(例如)将validate: 添加到我的rules= 中(例如):rules= required: value: true, message: "This field is required." , validate: emailEqual: value =&gt; (value === getValues().email) || "Emails don't match." refregister mumbo jumbo 是用于 React 实现而不是 React-Native,我想...

以上是关于React-hook-form 输入字段匹配验证最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

react-hook-form 的 DefaultValues 未将值设置为 React JS 中的输入字段

如何验证反应选择

React JS 多个提交按钮 react-hook-form

如果输入在材料 ui 对话框中,react-hook-form 的 setValue 方法不起作用

如何在反应中验证多步表单

使用 Yup 的 react-hook-form 解析器类型错误