使用react-hook-form处理多表单错误:合并错误对象方案
实现思路
1. 用React状态实时同步错误对象
直接用useState维护一个全局的错误集合,每个表单通过useEffect监听自身的错误变化,一旦更新就同步到全局对象里。
示例代码:
import { useState, useEffect } from 'react'; import { useForm } from 'react-hook-form'; function App() { // 初始化统一错误对象 const [combinedErrors, setCombinedErrors] = useState({}); // 表单1实例 const { register, formState: { errors: form1Errors } } = useForm({ defaultValues: { firstname: '' } }); // 表单2实例 const { register: register2, formState: { errors: form2Errors } } = useForm({ defaultValues: { email: '' } }); // 监听表单1错误变化,同步到统一对象 useEffect(() => { setCombinedErrors(prev => ({ ...prev, form1: form1Errors })); }, [form1Errors]); // 监听表单2错误变化,同步到统一对象 useEffect(() => { setCombinedErrors(prev => ({ ...prev, form2: form2Errors })); }, [form2Errors]); // 此时combinedErrors就是你要的结构 console.log(combinedErrors); return ( <div> {/* 表单1 */} <form> <input {...register('firstname', { required: 'required field' })} /> {form1Errors.firstname && <p>{form1Errors.firstname.message}</p>} </form> {/* 表单2 */} <form> <input {...register2('email', { required: 'required field' })} /> {form2Errors.email && <p>{form2Errors.email.message}</p>} </form> </div> ); }
2. 封装自定义Hook复用逻辑
如果有多个表单,写个自定义Hook来统一处理错误合并,避免重复代码。
示例代码:
import { useState, useEffect } from 'react'; function useCombinedFormErrors(formConfigs) { const [combinedErrors, setCombinedErrors] = useState({}); useEffect(() => { const newErrors = {}; formConfigs.forEach(({ formKey, formInstance }) => { newErrors[formKey] = formInstance.formState.errors; }); setCombinedErrors(newErrors); }, [formConfigs]); return combinedErrors; } // 使用方式 function App() { const form1 = useForm({ defaultValues: { firstname: '' } }); const form2 = useForm({ defaultValues: { email: '' } }); const combinedErrors = useCombinedFormErrors([ { formKey: 'form1', formInstance: form1 }, { formKey: 'form2', formInstance: form2 } ]); console.log(combinedErrors); // ... 表单渲染逻辑 }
3. 提交时一次性合并错误
如果不需要实时同步错误,只在提交所有表单的时候收集错误,直接在提交函数里拼接就行:
示例代码:
function App() { const form1 = useForm({ defaultValues: { firstname: '' } }); const form2 = useForm({ defaultValues: { email: '' } }); const handleSubmitAll = async () => { // 先触发所有表单的校验 const [form1Valid, form2Valid] = await Promise.all([ form1.trigger(), form2.trigger() ]); if (form1Valid && form2Valid) { // 校验通过,执行提交逻辑 } else { // 合并错误对象 const combinedErrors = { form1: form1.formState.errors, form2: form2.formState.errors }; console.log(combinedErrors); // 这里可以处理错误提示或其他逻辑 } }; return ( <div> {/* 表单1和表单2渲染 */} <button onClick={handleSubmitAll}>提交所有表单</button> </div> ); }
内容的提问来源于stack exchange,提问作者Baskar R
相关产品推荐
相关产品推荐

