如何在React Hook Form中动态更新resolver适配新增的动态表单字段?
问题解决方案
1. 动态更新resolver
你可以借助React Hook Form提供的updateResolver方法,结合state管理动态变化的Yup校验规则实现需求,完整实现逻辑如下:
首先调整初始化逻辑,将基础校验规则存入state:
import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as Yup from 'yup'; const someModelObject = { name: "", isActive: 0, date: null }; // 基础固定字段的校验规则 const baseValidationSchema = Yup.object().shape({ name: Yup.string().required(), isActive: Yup.number().required(), date: Yup.number().notRequired() }); function DynamicForm() { // 用state存储当前生效的校验schema const [validationSchema, setValidationSchema] = useState(baseValidationSchema); const { reset, updateResolver, getValues } = useForm({ defaultValues: someModelObject, resolver: yupResolver(validationSchema) });
拿到API响应后,动态拼接校验规则并更新resolver:
// 接口请求成功后执行 const moreCustomFieldsFromAPI = { custom1: "", custom2: "" }; // 按业务需求生成动态字段的校验规则,可根据接口返回的字段配置灵活调整 const customFieldsSchema = Yup.object().shape({ custom1: Yup.string().required(), custom2: Yup.number().notRequired() }); // 合并基础规则与动态字段规则 const newSchema = baseValidationSchema.concat(customFieldsSchema); // 更新state与表单resolver setValidationSchema(newSchema); updateResolver(yupResolver(newSchema)); // 重置表单值 reset({ ...someModelObject, ...moreCustomFieldsFromAPI });
2. getValues()返回格式化值
有两种常用实现方案,可按需选择:
- 手动封装格式化方法,适合规则灵活、需要特殊处理的场景:
const getFormattedValues = () => { const rawValues = getValues(); return { ...rawValues, // 按字段要求做类型转换 isActive: Number(rawValues.isActive), name: String(rawValues.name).trim(), custom2: rawValues.custom2 ? parseInt(rawValues.custom2, 10) : null }; }; // 调用时直接使用封装方法即可 const formattedValues = getFormattedValues();
- 借助Yup自带的
cast方法做类型转换,适合类型规则已经在校验schema中定义的场景,无需重复编写转换逻辑:
// 直接用当前生效的校验schema转换原始值 const rawValues = getValues(); const formattedValues = validationSchema.cast(rawValues);
注意:如果选择cast方案,只需要在生成动态字段校验schema时明确字段类型,后续新增字段无需修改格式化逻辑,自动适配规则。
内容的提问来源于stack exchange,提问作者Akshit W.
相关产品推荐
相关产品推荐

