【问题标题】:React Hook Form won't show error messagesReact Hook Form 不会显示错误信息
【发布时间】:2022-01-03 12:39:01
【问题描述】:

我有一个非常棘手的生日验证。

sandbox

只要用户尝试输入小于 18 岁的生日,表单就会更新为今天减去 18 岁的日期。现在,当我更仔细地研究它时,我希望以某种方式集成一个通知,以便用户基本上知道他/她的生日未被接受。为此,我试图在我的表单组件中显示一个处理错误消息的跨度:

{errors.birthdate && (
   <span className="text-xs text-red-700">
      {errors.birthdate.message}
   </span>
)}

我还有一个验证功能:

const validate = (date) =>
  isOlderThen18Years(date) || "You must be at least 18 years old";

发生了什么,至于重置我在 SelectBirthDay 中使用 useEffect 的日期:

useEffect(() => {
    if (!isOlderThen18Years(value)) {
      onChange(
        set(new Date(), { year: getYear(value) }),
      );
    }  
  }, [value, onChange]);

所以这会重置日期,但是如何显示错误消息?所以两者同时发生? Surele 我可以使用某种警报。但是是否可以根据 selectBirthDay 组件中的 useEffect 结果实际显示表单组件中的跨度?

【问题讨论】:

    标签: reactjs next.js react-hook-form


    【解决方案1】:

    通过将错误消息传递给&lt;SelectBirthDay /&gt; 中的onChange 处理程序,您非常接近。

    我认为一个不错的选择是将您的日期选择作为一个组件分开,然后在那里处理信息消息。通过这种方式,它与 &lt;Form /&gt; 组件分离,后者不必为用户知道此信息消息,因为它实际上不是表单字段的验证消息。

    我还建议将年份的生成移至&lt;SelectBirthYear /&gt; 组件。

    &lt;SelectBirthDate /&gt;

    import { useState } from "react";
    import { SelectBirthDay } from "./SelectBirthDay";
    import { SelectBirthMonth } from "./SelectBirthMonth";
    import { SelectBirthYear } from "./SelectBirthYear";
    
    export const SelectBirthDate = ({ onChange, ...field }) => {
      const [invalidMessage, setInvalidMessage] = useState();
    
      const handleChange = (value, invalidMessage) => {
        onChange(value);
        setInvalidMessage(invalidMessage);
      };
      return (
        <>
          <div className="sm:col-span-2 grid grid-cols-3 gap-4 mb-2">
            <div className="mt-1">
              <SelectBirthYear onChange={handleChange} {...field} />
            </div>
            <div className="mt-1">
              <SelectBirthMonth onChange={handleChange} {...field} />
            </div>
            <div className="mt-1">
              <SelectBirthDay onChange={handleChange} {...field} />
            </div>
          </div>
          <span className="mt-2 text-sm text-gray-500">{invalidMessage}</span>
        </>
      );
    };
    

    &lt;SelectBirthDay /&gt;

    export const SelectBirthDay = ({ value, onChange }) => {
      const handleChange = (date) => onChange(set(value, { date: date.getDate() }));
    
      const days = eachDayOfInterval({
        start: startOfMonth(value),
        end: endOfMonth(value)
      });
    
      useEffect(() => {
        if (!isOlderThen18Years(value)) {
          onChange(
            set(new Date(), { year: getYear(value) }),
            "Selected Date was not older then 18 years - automatically reset to the earliest possible date"
          );
        }
      }, [value, onChange]);
      
      return ...
    

    &lt;Form /&gt;

    <Controller
      control={control}
      name="birthdate"
      rules={{ validate }}
      render={({ field: { ref, ...field } }) => (
        <SelectBirthDate {...field} />
      )}
    />
    {errors.birthdate && (
      <span className="text-xs text-red-700">
        {errors.birthdate.message}
      </span>
    )}
    

    【讨论】:

    • 其实正如你所说,它不再是真正的错误了,所以可以从表格中取出规则以及errors.birthdate。 validate 函数总是比 18 早,因为组件无论如何都会重置生日。我做对了吗?非常感谢!
    • 是的,你是对的 - 你现在可以删除 &lt;Form /&gt; 中的 validate。我想你也可以将isOlderThen18Years&lt;Form /&gt; 移动到&lt;SelectBirthDay /&gt; - 这样&lt;Form /&gt; 将不再包含任何关于&lt;SelectBirthDate /&gt; 实现细节的逻辑。简洁一些,遵循SoC原理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 2023-04-09
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 2020-12-25
    相关资源
    最近更新 更多