【问题标题】:React-hook-form input fields match validation best practiceReact-hook-form 输入字段匹配验证最佳实践
【发布时间】: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 等)

【问题讨论】:

    标签: reactjs react-hook-form


    【解决方案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,我想...
    猜你喜欢
    • 2021-05-25
    • 2016-01-09
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多