React Hook Form表单值无法更新问题求助
表单修改值被旧值覆盖的问题修复
问题描述
提交表单后将数据保存到状态并持久化到localStorage,从localStorage获取值填充表单后,修改字段时新输入的值会立即被旧值覆盖,无法正常更新。
问题原因
useForm初始化时依赖defaultValues状态,当useEffect中更新defaultValues时,会触发useForm重新初始化,覆盖用户的实时输入。- 同时使用
setDefaultValues和setValue设置表单值,导致状态冲突,旧值会强制覆盖新输入。
修复方案
1. 移除多余的defaultValues状态,直接从localStorage初始化表单默认值
不需要维护单独的defaultValues状态,而是在useForm初始化时直接读取localStorage的值作为默认值,避免状态同步问题。
2. 改用reset方法设置表单值,而非同时更新状态和调用setValue
useForm提供的reset方法可以一次性重置整个表单的值,比循环调用setValue更可靠,也避免和状态更新冲突。
修改后的代码
状态定义(简化)
const [submittedData, setSubmittedData] = useState<PersonalInformationFormInput | null>(null);
useForm初始化
// 直接从localStorage获取初始默认值 const initialDefaultValues = typeof localStorage !== "undefined" ? JSON.parse(localStorage.getItem("personalInformationData") || JSON.stringify({ firstName: "" })) : { firstName: "" }; const { register, formState: { errors }, watch, handleSubmit, setValue, formState, trigger, setError, reset // 引入reset方法 } = useForm<PersonalInformationFormInput>({ resolver: zodResolver(FormSchema), defaultValues: initialDefaultValues, });
初始化逻辑(简化)
useEffect(() => { if (typeof localStorage !== "undefined") { const storedData = localStorage.getItem("personalInformationData"); if (storedData) { const parsedData = JSON.parse(storedData); setSubmittedData(parsedData); // 用reset方法设置表单值,替代setValue循环和setDefaultValues reset(parsedData); } } }, [reset]); // 依赖reset方法
提交逻辑(简化)
const onSubmit = (data: PersonalInformationFormInput) => { if (!formState.isValid) { console.log("Validation errors:", formState.errors); return; } setSubmittedData(data); localStorage.setItem("personalInformationData", JSON.stringify(data)); // 提交后若需重置表单可调用reset(data),无需更新defaultValues };
表单片段(不变)
<form onSubmit={handleSubmit(onSubmit)}> <div> <h2> First name <span>*</span> </h2> <input type="text" {...register("firstName")} /> {errors?.firstName?.message && ( <p> {errors.firstName.message} </p> )} </div> <div> <button type="submit" > Next Step </button> </div> </form>
关键说明
- 移除
defaultValues状态后,避免了useForm因状态更新而重新初始化的问题。 - 使用
reset方法统一设置表单值,确保表单内部状态和显示值一致。 - 初始默认值直接从localStorage读取,保证页面加载时表单能正确填充已有数据。
内容的提问来源于stack exchange,提问作者Dave Odipo
相关产品推荐
相关产品推荐

