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

如何在使用useForm校验表单时配合localStorage持久化数据

问题根源
  • react-hook-form的register方法会自动给输入框注入内部状态同步需要的onChange、ref、name属性,你手动给input加的value属性、自定义handleChange事件会覆盖这些注入逻辑,导致表单库内部拿不到最新的输入值,校验逻辑自然失效。
  • 你额外维护的values状态属于重复逻辑:react-hook-form本身就内置了表单状态管理、默认值注入、值变更监听能力,完全不需要自己再写一套状态同步逻辑对接localStorage。
修复实现

直接用useForm自带的能力对接持久化即可,不需要单独维护表单state:

  1. 初始化useForm时,通过defaultValues配置项直接读取localStorage的缓存值作为表单初始值,实现刷新后自动回填
  2. 用watch方法监听全表单的值变化,值变更时自动同步到localStorage
  3. 输入框只需要绑定register即可,不需要手动写value属性和自定义onChange处理,校验规则直接写在register的第二个参数中就能正常触发

完整可运行代码:

import React, { useEffect } from "react";
import "./App.css"
import { useForm } from "react-hook-form";

// 读取localStorage缓存的表单值
const getStoredForm = () => {
  const storedValues = localStorage.getItem("form");
  if(!storedValues) return {
      name: "",
      age: ""
    }
  return JSON.parse(storedValues);
}

function Home() {
  const {
    register, 
    handleSubmit, 
    watch,
    formState: { errors }
  } = useForm({
    // 初始化直接用缓存值作为默认值
    defaultValues: getStoredForm()
  });

  const onSubmit = async data => { 
    console.log("提交的表单数据", data); 
  };

  // 监听所有表单值变化,自动同步到localStorage
  const allFormValues = watch()
  useEffect(()=>{
    localStorage.setItem("form", JSON.stringify(allFormValues))
  }, [allFormValues])
  
  return (
    <div className="container">
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <input 
            {...register("name", { required: "姓名不能为空" })} 
            placeholder="请输入姓名"  
          />
          {/* 校验错误提示 */}
          {errors.name && <span style={{color: 'red'}}>{errors.name.message}</span>}
        </div>
        <div>
          <input 
            {...register("age", { 
              required: "年龄不能为空",
              min: { value: 1, message: "年龄不能小于1岁" },
              valueAsNumber: true
            })} 
            placeholder="请输入年龄"
          />
          {errors.age && <span style={{color: 'red'}}>{errors.age.message}</span>}
        </div>
        <button type="submit">提交</button>
      </form>
    </div>
  )
}

export default Home;
补充说明

如果你后续有特殊的输入控制需求(比如输入内容实时格式化、对接第三方自定义输入组件),不要手动覆盖register注入的属性,改用react-hook-form提供的Controller组件或者useController钩子对接受控组件即可,不会破坏内部的状态同步和校验逻辑。

内容的提问来源于stack exchange,提问作者ceaiius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:12:58