You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React Hook Form实现内联(onBlur)及页面级(提交)错误展示

React Hook Form 实现分场景错误提示

这里给你实现两种错误提示的具体方案,完全匹配你的需求:内联错误在字段失焦(onBlur)时显示,页面级错误只在点击「下一步」提交时显示。

核心逻辑

利用 React Hook Form 的字段校验触发机制和状态管理:

  • 内联错误:通过trigger在字段失焦时单独校验该字段,结合errors和touched状态控制显示。
  • 页面级错误:通过表单提交后的isSubmitted状态,判断是否存在全局错误并汇总显示。

具体实现步骤

1. 初始化表单

先通过useForm初始化表单,设置默认值,同时解构需要用到的方法和状态:

import { useForm } from "react-hook-form";

function StepForm() {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitted },
    trigger
  } = useForm({
    defaultValues: {
      email: "",
      password: ""
    }
  });

2. 实现内联级错误(onBlur触发)

给每个输入字段注册校验规则,同时在onBlur事件中调用trigger触发该字段的校验。内联错误只在字段被失焦过,或者表单已提交时显示:

<div>
  <label>邮箱</label>
  <input
    {...register("email", {
      required: "邮箱不能为空",
      pattern: {
        value: /^\S+@\S+$/i,
        message: "请输入有效的邮箱地址"
      }
    })}
    onBlur={() => trigger("email")}
  />
  {/* 内联错误提示 */}
  {errors.email && (errors.email.touched || isSubmitted) && (
    <span style={{ color: "red", fontSize: "12px" }}>
      {errors.email.message}
    </span>
  )}
</div>
  • trigger("email"):手动触发单个字段的校验,确保失焦时就校验并显示错误。
  • errors.email.touched:判断字段是否被失焦过,保证只有用户触碰过该字段才显示内联错误。

3. 实现页面级错误(提交时显示)

页面级错误放在表单顶部,仅在点击「下一步」提交表单后,且存在校验错误时显示:

{isSubmitted && Object.keys(errors).length > 0 && (
  <div style={{ color: "red", marginBottom: "16px" }}>
    请修正以下错误:{Object.values(errors).map(err => err.message).join("、")}
  </div>
)}
  • isSubmitted:标记表单是否被提交过,确保只有提交后才显示全局错误汇总。

4. 提交逻辑

通过handleSubmit包裹提交函数,只有当所有字段校验通过时,才会执行后续的下一步逻辑:

const onSubmit = (data) => {
  // 这里写校验通过后的下一步逻辑,比如页面跳转、数据提交等
  alert("校验通过,进入下一步");
};

// 表单绑定提交事件
<form onSubmit={handleSubmit(onSubmit)}>
  {/* 表单内容 */}
  <button type="submit">下一步</button>
</form>

完整示例代码

import { useForm } from "react-hook-form";

function StepForm() {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitted },
    trigger
  } = useForm({
    defaultValues: {
      email: "",
      password: ""
    }
  });

  const onSubmit = (data) => {
    alert("表单校验通过,进入下一步");
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} style={{ padding: "20px" }}>
      {/* 页面级错误提示 */}
      {isSubmitted && Object.keys(errors).length > 0 && (
        <div style={{ color: "red", marginBottom: "16px" }}>
          请修正以下错误:{Object.values(errors).map(err => err.message).join("、")}
        </div>
      )}

      <div style={{ marginBottom: "16px" }}>
        <label style={{ display: "inline-block", width: "80px" }}>邮箱</label>
        <input
          {...register("email", {
            required: "邮箱不能为空",
            pattern: {
              value: /^\S+@\S+$/i,
              message: "请输入有效的邮箱地址"
            }
          })}
          onBlur={() => trigger("email")}
          style={{ padding: "4px" }}
        />
        {errors.email && (errors.email.touched || isSubmitted) && (
          <div style={{ color: "red", fontSize: "12px", marginTop: "4px" }}>
            {errors.email.message}
          </div>
        )}
      </div>

      <div style={{ marginBottom: "16px" }}>
        <label style={{ display: "inline-block", width: "80px" }}>密码</label>
        <input
          type="password"
          {...register("password", {
            required: "密码不能为空",
            minLength: {
              value: 6,
              message: "密码长度不能少于6位"
            }
          })}
          onBlur={() => trigger("password")}
          style={{ padding: "4px" }}
        />
        {errors.password && (errors.password.touched || isSubmitted) && (
          <div style={{ color: "red", fontSize: "12px", marginTop: "4px" }}>
            {errors.password.message}
          </div>
        )}
      </div>

      <button type="submit" style={{ padding: "6px 16px" }}>下一步</button>
    </form>
  );
}

export default StepForm;

关键细节说明

  • 内联错误的显示条件:确保用户触碰过字段(失焦)或表单已提交,避免页面刚加载就显示错误。
  • 页面级错误仅在提交后显示:通过isSubmitted状态控制,不会提前干扰用户输入。
  • 单个字段校验:用trigger精准触发对应字段的校验,避免全局校验提前触发。

内容的提问来源于stack exchange,提问作者Tanu Agrawal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 06:55:10