React Hook Form useFieldArray结合Yup校验错误不消失问题求助
解决React Hook Form useFieldArray结合Yup动态表单校验失效问题
问题根源
你的代码存在三个核心错误,直接导致校验不生效、错误提示无法清除:
字段名称不匹配
- Schema和useFieldArray使用的字段名是
type_of_transports_details,但useForm的defaultValues里对应的数组名是type_of_the_transport_details,名称不一致导致表单无法关联校验规则。
- Schema和useFieldArray使用的字段名是
Register路径格式错误
- 动态数组字段的register路径应该遵循
数组名[索引].属性名格式,你写成了数组名.属性名.索引,导致React Hook Form无法正确绑定字段值到表单状态。
- 动态数组字段的register路径应该遵循
默认值类型不匹配
- Yup规则里
count/price/total定义为nullable().number(),但defaultValues里这些字段设为空字符串"",类型不匹配会触发typeError且无法通过校验。
- Yup规则里
修正后的完整代码
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
相关产品推荐
相关产品推荐

