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

React Hook Form动态字段添加错误提示遇TypeScript语法问题

React Hook Form动态字段错误提示修复方案

问题

在TypeScript环境下使用React Hook Form的useFieldArray实现动态字段时,无法正常获取错误提示(非动态字段工作正常)。原代码中errors.userInput[index].type?.message会触发errors.userInput可能未定义的类型错误,导致错误信息无法渲染。

原问题代码

const form = useForm<FormData>({
  defaultValues: {
    userInput: [
      {
        type: "",
        category: "",
        subcategory: "",
      },
    ],
  },
});

const { register, handleSubmit, control, formState } = form;
const { errors } = formState;

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

return (
  <div>
    <form onSubmit={handleSubmit(onSubmit)} noValidate>
      <div>
        {fields.map((field, index) => {
          return (
            <div key={field.id}>
              <label>Add income or an expense?</label>
              <select
                defaultValue=""
                {...register(`userInput.${index}.type` as const, {
                  required: { value: true, message: "Field is required" },
                })}
              >
                <option value="expense">Expense</option>
                <option value="income">Income</option>
                <option value="liability">Liability</option>
              </select>
              <p className="error">{errors.userInput[index].type?.message}</p>
            </div>
          );
        })}
      </div>
    </form>
  </div>
);

问题原因

React Hook Form的errors对象仅在字段校验失败时才会生成对应层级的属性。当userInput数组中没有校验失败的项时,errors.userInput会是undefined,直接访问errors.userInput[index]会触发类型错误和运行时错误。而非动态字段的errors.type?.message使用了可选链,仅在type存在时访问message,所以不会报错。

修复方案

对errors对象的每一层嵌套都添加可选链操作符(?.),确保某一层属性不存在时不会抛出错误:

将错误提示行修改为:

<p className="error">{errors.userInput?.[index]?.type?.message}</p>

修改后的完整代码片段

{fields.map((field, index) => {
  return (
    <div key={field.id}>
      <label>Add income or an expense?</label>
      <select
        defaultValue=""
        {...register(`userInput.${index}.type` as const, {
          required: { value: true, message: "Field is required" },
        })}
      >
        <option value="expense">Expense</option>
        <option value="income">Income</option>
        <option value="liability">Liability</option>
      </select>
      {/* 这里添加了多层可选链 */}
      <p className="error">{errors.userInput?.[index]?.type?.message}</p>
    </div>
  );
})}

补充说明

如果需要在没有错误时隐藏错误提示元素,可以结合条件渲染:

{errors.userInput?.[index]?.type?.message && (
  <p className="error">{errors.userInput?.[index]?.type?.message}</p>
)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:55:59