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

React Hook Form表单值无法更新问题求助

表单修改值被旧值覆盖的问题修复

问题描述

提交表单后将数据保存到状态并持久化到localStorage,从localStorage获取值填充表单后,修改字段时新输入的值会立即被旧值覆盖,无法正常更新。

问题原因

  1. useForm初始化时依赖defaultValues状态,当useEffect中更新defaultValues时,会触发useForm重新初始化,覆盖用户的实时输入。
  2. 同时使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:08:19