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

React Hook Form useFieldArray结合Yup校验错误不消失问题求助

解决React Hook Form useFieldArray结合Yup动态表单校验失效问题

问题根源

你的代码存在三个核心错误,直接导致校验不生效、错误提示无法清除:

  1. 字段名称不匹配

    • Schema和useFieldArray使用的字段名是type_of_transports_details,但useForm的defaultValues里对应的数组名是type_of_the_transport_details,名称不一致导致表单无法关联校验规则。
  2. Register路径格式错误

    • 动态数组字段的register路径应该遵循数组名[索引].属性名格式,你写成了数组名.属性名.索引,导致React Hook Form无法正确绑定字段值到表单状态。
  3. 默认值类型不匹配

    • Yup规则里count/price/total定义为nullable().number(),但defaultValues里这些字段设为空字符串"",类型不匹配会触发typeError且无法通过校验。

修正后的完整代码

1. 修正Schema与defaultValues的字段名称、默认值类型

import { useForm, useFieldArray } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";

const schema = yup.object().shape({
  type_of_transports_details: yup.array().of(
    yup.object().shape({
      count: yup.number().nullable().typeError('Sayısal bir değer giriniz.').required("Taşıma sayısı alanı zorunludur, lütfen giriş yapınız."),
      price: yup.number().nullable().typeError('Sayısal bir değer giriniz.').required("Fiyat alanı zorunludur, lütfen giriş yapınız."),
      total: yup.number().nullable().typeError('Sayısal bir değer giriniz.').required("Toplam alanı zorunludur, lütfen giriş yapınız."),
    })
  ),
});

const {
  control,
  register,
  handleSubmit,
  formState: { errors },
  setValue,
  getValues,
  reset,
  setFocus,
  clearErrors,
  resetField,
  setError,
  watch,
} = useForm({
  resolver: yupResolver(schema),
  defaultValues: {
    upload_addresses: [{
      company_name: "",
      code: "",
      city: "",
      country: "",
      address: "",
      detail: "",
    }],
    // 修正数组名称,数字类型字段默认值设为null
    type_of_transports_details: [{
      transport_type: "",
      count: null,
      currency_name: "",
      currency_value: "",
      price: null,
      total: null,
    }],
  }
});

const { 
  fields: transportFields, 
  append: transportAppend, 
  remove: transportRemove, 
  update: transportUpdate 
} = useFieldArray({
  control,
  name: "type_of_transports_details",
});

2. 修正表单中的Register路径

{transportFields.map((field, index) => {
  return (
    <tr key={field.id} style={{ backgroundColor: "#E8EAE6" }}>
      <td className="tablelj align-middle">
        <label htmlFor={`numberOfTransports-${index}`} className="form-label">{field.type} TAŞIMA TİPİ ÜCRETLERİ</label>
      </td>
      <td>
        <div className="row">
          <div className="col-lg col-12">
            <input
              type="number"
              className="form-control"
              placeholder="Taşıma Sayısı"
              // 修正为正确的数组索引路径格式
              {...register(`type_of_transports_details[${index}].count`)}
            />
            {errors?.type_of_transports_details?.[index]?.count?.message && (
              <span className="text-danger">
                {errors.type_of_transports_details[index].count.message}
              </span>
            )}
          </div>
          {/* price字段同理修正路径 */}
          <div className="col-lg col-12">
            <input
              type="number"
              className="form-control"
              placeholder="Fiyat"
              {...register(`type_of_transports_details[${index}].price`)}
            />
            {errors?.type_of_transports_details?.[index]?.price?.message && (
              <span className="text-danger">
                {errors.type_of_transports_details[index].price.message}
              </span>
            )}
          </div>
          {/* total字段同理修正路径 */}
          <div className="col-lg col-12">
            <input
              type="number"
              className="form-control"
              placeholder="Toplam"
              {...register(`type_of_transports_details[${index}].total`)}
            />
            {errors?.type_of_transports_details?.[index]?.total?.message && (
              <span className="text-danger">
                {errors.type_of_transports_details[index].total.message}
              </span>
            )}
          </div>
          <div className="col-lg col-12">
            <button type="button" onClick={() => transportRemove(index)}>Sil</button>
          </div>
        </div>
      </td>
    </tr>
  )
})}

额外说明

  • 所有动态字段的register路径必须遵循数组名[索引].属性名格式,React Hook Form才能正确追踪字段值变化并触发Yup校验。
  • 对于nullable()的数字类型字段,默认值需设为null而非空字符串,避免类型不匹配导致的校验错误。
  • 无需手动调用clearErrors,React Hook Form会在字段值符合校验规则时自动清除错误提示。

内容的提问来源于stack exchange,提问作者Ubeydullah Yılmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:54:23