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

React-Hook-Form中useFieldArray添加元素时验证前序数组项的需求

解决React-Hook-Form中useFieldArray添加新字段前校验前序项的问题

核心思路

在调用append添加新数组项之前,手动触发已有数组项的字段校验,通过trigger方法指定需要校验的字段路径,校验全部通过后再执行添加操作。React-Hook-Form的trigger会自动更新表单错误状态,错误信息会直接绑定到对应字段的错误提示组件上。

具体实现代码

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

type FormValues = {
  items: {
    name: string;
    email: string;
  }[];
};

export default function DynamicForm() {
  const { register, control, trigger, formState: { errors } } = useForm<FormValues>({
    defaultValues: {
      items: [{ name: "", email: "" }]
    }
  });

  const { fields, append } = useFieldArray({
    control,
    name: "items"
  });

  const handleAddItem = async () => {
    // 收集所有已有数组项的字段路径,批量触发校验
    const fieldPaths = fields.flatMap((_, index) => [
      `items.${index}.name`,
      `items.${index}.email`
    ]);

    // 触发校验,返回布尔值表示是否全部通过
    const isValid = await trigger(fieldPaths);

    if (isValid) {
      // 校验通过,添加新的空项
      append({ name: "", email: "" });
    }
    // 校验不通过时,errors会自动更新,对应字段的错误提示会显示
  };

  return (
    <form>
      {fields.map((item, index) => (
        <div key={item.id} style={{ marginBottom: "1rem" }}>
          <div>
            <label>姓名</label>
            <input
              {...register(`items.${index}.name`, {
                required: "姓名不能为空",
                minLength: { value: 2, message: "姓名至少2个字符" }
              })}
              placeholder="请输入姓名"
            />
            {errors.items?.[index]?.name && (
              <span style={{ color: "red" }}>{errors.items[index].name.message}</span>
            )}
          </div>
          <div>
            <label>邮箱</label>
            <input
              {...register(`items.${index}.email`, {
                required: "邮箱不能为空",
                pattern: {
                  value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
                  message: "请输入合法邮箱"
                }
              })}
              placeholder="请输入邮箱"
            />
            {errors.items?.[index]?.email && (
              <span style={{ color: "red" }}>{errors.items[index].email.message}</span>
            )}
          </div>
        </div>
      ))}

      <button type="button" onClick={handleAddItem}>添加新项</button>
    </form>
  );
}

关键细节说明

  • 批量校验字段:通过fields.flatMap生成所有已有数组项的完整字段路径(比如items.0.name、items.0.email),传给trigger实现批量校验。
  • 校验结果判断:trigger返回Promise,resolve为布尔值,true表示所有指定字段校验通过,此时才执行append。
  • 错误自动展示:只要触发了校验,React-Hook-Form会自动更新errors对象,对应索引的字段错误提示会根据errors.items?.[index]?.字段名的存在性显示。

可选优化:仅校验最后一个前序项

如果只需要校验最后一个已存在的数组项(而非全部),可以修改handleAddItem:

const handleAddItem = async () => {
  if (fields.length === 0) {
    append({ name: "", email: "" });
    return;
  }

  const lastIndex = fields.length - 1;
  const fieldPaths = [
    `items.${lastIndex}.name`,
    `items.${lastIndex}.email`
  ];

  const isValid = await trigger(fieldPaths);

  if (isValid) {
    append({ name: "", email: "" });
  }
};

内容的提问来源于stack exchange,提问作者sabbir 07

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:40:24